python支持面向对象的三大特征:封装、继承、多态——用途不明,暂且记录
# 基本概念与操作
名词 | name | 定义 | 代码 | 举例 |
---|---|---|---|---|
类 | class | 一批对象的抽象 | A | 人类 |
对象(实例) | object(instance) | 具体存在的实体 | A() | 人 |
类与对象的关系:类的主要作用是重复创建具有相同特征的对象【类名()】
创建类
class 类名: #语法上,合法即可;可读性上,由单词连缀而成,首字母大写
"说明文档"
执行语句 #直接执行的命令
类变量
类方法
类成员
同一个类中,各成员可以互相调用,不受其位置约束
-
变量
|类型|创建位置|从属于|适用范围|
|:----|:----|:----|:----|
|类变量|类下|类【A】|类中所有成员均可调用|
|实例变量|方法中|类的对象【A()】|专属于特定方法| -
方法
|类型|内部变量|
|:----|:----|
|构造方法__init__|在类实例化之后调用|
|普通实例方法|专属于该方法,不可在类外调用|
- 类的实例化:实质上调用了类的构造方法,缺省时,python自带只含self参数的构造方法
class A:
x = 1 #类变量
def __init__(self, y=2): #构造方法
self.y = y #【y】:构造方法中的实例变量
def B(self, z): #普通实例方法
print(z) #【z】:普通实例方法的实例变量
类的基本操作
class A:
x = 1
def B(self): pass
a = A()
def C(self): pass
类成员 | 操作 | 类名【A】 | 变量名【a】 | 类的实例化【A()】 |
---|---|---|---|---|
类变量 | 调用 | A.x | a.x | A().x |
增加 | A.new = | a.new = | - | |
删除 | del A.x | del a.x | - | |
重新赋值 | A.x = | - | - | |
实例变量 | 增加 | a.new = | ||
类方法 | 调用 | - | a.B() | A().B() |
增加 | A.new = C | a.new = C | - | |
删除 | del A.B | del a.B |
- 增加:给不存在的类成员赋值
- 通过变量名【a】增加的实例变量只属于【a】,跟类没有关系
# self
在类方法中是必须的,绑定到类的实例,调用类方法时,不需要传入self对应的参数
类成员互相调用时,self不可缺省——原因:此时,类尚未实例化
class A:
def b(self): pass
def c(self): self.b() #调用b方法时,self不可省略
绑定方法:
- 在类的内部,由python自动绑定
- 在类的外部,手动绑定:类名.类方法名(类名)
class A: pass
def B(self):pass
A.new = B #把方法B添加到类A中
A.new(A) #手动绑定self与类
A.new #调用A的新方法【new】
# 函数装饰器@
用已有的函数A修饰另一函数B,A可以是内置的函数,也可以是自定义的函数
作用:将B作为A的参数传入,然后运行A,相当于A(B),以下两段代码等效——感觉是鸡肋
代码一:
def A(a): print(a)
def B(): pass
A(B)
>>> <function B at 0x000000000212C268>
代码二
def A(a): print(a)
@A
def B(): pass
B
>>> <function B at 0x000000000212C268>
# 常用作函数装饰器的函数property()
功能:将方法定义成属性
语法:class property([fget[, fset[, fdel[, doc]]]])
各参数对应的函数依次为:获取属性值、设置属性值、删除属性值、属性描述信息
内置的方法:getter, setter, deleter, docstring
参数数量与函数属性的对应关系 | ||||
---|---|---|---|---|
参数数量 | 可读 | 可写 | 可删除 | 说明文档 |
1 | YES | NO | NO | NO |
2 | YES | YES | NO | NO |
3 | YES | YES | YES | NO |
4 | YES | YES | YES | YES |
使用property为创建方法的属性,有两种途径
- 先定义方法,然后把方法作为property的参数传入
- 直接用property本身或property内部的函数修饰方法
class A:
def __init__(self):
self._x = None #创建实例变量
def getx(self):
return self._x #返回实例变量的值
def setx(self, value):
self._x = value #增加新的实例变量
def delx(self):
del self._x #删除实例变量
x = property(getx, setx, delx, "说明文档")
class A:
def __init__(self): self._x = None
@property
def x(self): return self._x
@x.setter
def x(self, value): self._x = value
如果只向property传入一个参数,可以方便地创建只读属性
class A:
def __init__(self): self._x = 1
@property
def B(self): return self._x
# 隐藏和封装
python没有真隐藏,只有假隐藏
python会创建一个新类【_原类名】,把以双划线开头的成员放进去,其实还是可以访问的
# 类的继承
子类继承父类的方法,未指定时,默认继承object类。一个子类可以继承多个父类(不推荐)
继承的语法:class 子类名(父类1,父类2,…)
方法重名时的优先级:子类 > 父类;排名靠前的父类 > 排名靠后的父类
优先级低的方法可以通过类名直接调用
构造方法的继承:默认只继承第一个父类的构造方法,如果想继承多个父类的构造方法,需要为子类重写构造方法。重写时,可以用父类名直接调用父类的构造方法
class A:
def __init__(self,x): self.x = x
def m(self): print(self.x)
class B:
def __init__(self,y): self.y = y
def n(self): print(self.y)
class C(A,B):
def __init__(self,x,y):
A.__init__(self,x)
B.__init__(self,y)
c = C(1,2)
c.m()
c.n()
类的关系
代码 | 返回内容 |
---|---|
base | 优先级最高的父类 |
bases | 所有直接父类(元组形式) |
subclasses() | 所有直接子类(列表形式) |
issubclass(A,B) | 检查A是否为B的子类,B可以是元组 |
class A: pass
class B(A): pass
class C(A): pass
print(A.__subclasses__())
>>> [<class '__main__.B'>, <class '__main__.C'>]
# 类的函数
代码 | 作用 |
---|---|
slots(a,b,c) 在类下第一行输入 | 限制对类的对象【a】的修改 只允许修改a,b,c方法/属性 |
type() | 类都是用type()函数创建的,其类型都是【type】 |
metaclass | 将某些特征应用到所有类,自动执行 |
- slots的局限性:还是可以通过类名【A】直接修改类;对派生的子类无效
metaclass 用于创建类的类
步骤
- 设置特征。要继承type类并重写new方法
new: 在__init__之前被调用的特殊方法,用来创建当前类的对象并返回
参数:cls - 类,name - 类名,bases - 所有父类,attrs - 所有方法、属性的合集
- 把特征应用到类
class A(type):
def __new__(cls, name, bases, attrs):
return type.__new__(cls, name, bases, attrs)
class B(metaclass = A)
多态
多态性:变量执行方法时,指向不同对象
作用:可先确定方法【A().a()】,后确定对象,程序更加灵活
class A:
def a(self,x): x.draw(self) #调用draw方法的对象x稍后确定
class B:
def draw(self,y): print('B',y)
class C:
def draw(self, z): print('C',z)
A().a(B())
A().a(C())
>>>
B <__main__.A object at 0x0000000002F5DC50>
C <__main__.A object at 0x0000000002F5DC50>
定义枚举类 Enum
import enum
Season =enum.Enum(Season, ('spring', 'summer', 'fall', 'winter'))
类的对象有限且固定时,可将其定义为枚举类。如:季节只有春夏秋冬4个对象
类自带__member__属性,以字典形式返回所有实例
每个成员都有name和value两个属性,其中,value默认依次为1,2,3,4
程序报错:name ‘Season’ is not defined
isinstance(a,b) | 检查a是否为b的对象,B可以是元组 |
---|