前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python day7 面向对象编程 (1)

Python day7 面向对象编程 (1)

原创
作者头像
昆兰
发布2024-07-31 16:59:57
550
发布2024-07-31 16:59:57
举报
文章被收录于专栏:廖雪峰python学习笔记

面向对象编程 OOP

Object Oriented Programming,一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数

面向过程和面向对象

  • 面向过程,把函数继续切分为子函数
  • 面向对象,把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递

对象

自定义的对象数据类型就是面向对象中的类(Class)的概念

首先必须创建出这个学生对应的对象,然后,给对象发一个print_score消息,让对象自己把自己的数据打印出来

代码语言:python
代码运行次数:0
复制
class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def print_score(self):
        print('%s: %s' % (self.name, self.score))

类(Class)和实例(Instance)

面向对象最重要的概念就是类(Class)和实例(Instance)

Class是一种抽象概念,比如我们定义的Class——Student,是指学生这个概念,而实例(Instance)则是一个个具体的Student

代码语言:python
代码运行次数:0
复制
#class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object)
class Student(object):  
    pass

#创建建实例是通过类名+()实现的:
bart = Student()
# bart绑定一个name属性
bart.name = 'Bart Simpson'


#在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去
class Student(object):
    def __init__(self, name, score): #self,表示创建的实例本身
        self.name = name
        self.score = score

访问限制

由于外部代码还是可以自由地修改一个实例的属性,我们可以把属性的名称前加上两个下划线__,变成了一个私有变量(private),只有内部可以访问,外部不能访问

代码语言:python
代码运行次数:0
复制
class Student(object):
    def __init__(self, name, score): #self,表示创建的实例本身
        self.__name = name
        self.__score = score
        
        #利用方法使得外部代码可以访问
        def get_name(self): 
        return self.__name
        #利用外部代码修改score
        def set_score(self, score):
        self.__score = score

继承和多态

我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)

代码语言:python
代码运行次数:0
复制
class Animal(object):   #编写Animal类
    def run(self):
        print("Animal is running...")

class Dog(Animal):  #Dog类继承Amimal类,没有run方法
    pass

class Cat(Animal):  #Cat类继承Animal类,有自己的run方法
    def run(self):
        print('Cat is running...')
    pass

class Car(object):  #Car类不继承,有自己的run方法
    def run(self):
        print('Car is running...')

class Stone(object):  #Stone类不继承,也没有run方法
    pass

def run_twice(animal):
    animal.run()
    animal.run()

run_twice(Animal())
run_twice(Dog())
run_twice(Cat())
run_twice(Car())
run_twice(Stone())

输出结果

Animal is running... Animal is running...

Animal is running... Animal is running...

Cat is running... Cat is running...

Car is running... Car is running...

AttributeError: 'Stone' object has no attribute 'run'

由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思

这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。

获取对象信息

type()函数

它返回对应的Class类型。如果我们要在if语句中判断,就需要比较两个变量的type类型是否相同

  • 基本数据类型就是int,str
  • 对象是函数的话,用types模块中定义的常量:types.FunctionType,types.BuiltinFunctionType,types.LambdaType,types.GeneratorType

isinstance()函数(优先)

对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数

  • isinstance()判断的是一个对象是否是该类型本身,或者位于该类型的父继承链上
  • 还可以判断一个变量是否是某些类型中的一种,比如下面的代码就可以判断是否是list或者tuple
代码语言:python
代码运行次数:0
复制
>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
True

dir()函数

它返回一个包含字符串的list

仅把属性和方法列出来是不够的,配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态

代码语言:python
代码运行次数:0
复制
>>> class MyObject(object):
...     def __init__(self):
...         self.x = 9
...     def power(self):
...         return self.x * self.x
...
>>> obj = MyObject()
>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19

>>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404
404

>>> hasattr(obj, 'power') # 有属性'power'吗?
True
>>> getattr(obj, 'power') # 获取属性'power'
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
>>> fn # fn指向obj.power
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn() # 调用fn()与调用obj.power()是一样的
81

实例属性和类属性

为了统计学生人数,可以给Student类增加一个类属性,每创建一个实例,该属性自动增加

代码语言:python
代码运行次数:0
复制
class Student(object):

count = 0

def __init__(self, name):

self.name = name

Student.count += 1

发现没有直接点明init这个方法,在实例化对象的时候,应该是会自动调用一次这个方法

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 面向对象编程 OOP
    • 面向过程和面向对象
      • 对象
      • 类(Class)和实例(Instance)
      • 访问限制
      • 继承和多态
      • 获取对象信息
        • type()函数
          • isinstance()函数(优先)
            • dir()函数
            • 实例属性和类属性
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档