类
经典类 | 新式类 | |
---|---|---|
python2 | 默认 | 需要显式继承object |
python3 | 不支持 | 默认 |
__new__ |
不支持 | 支持 |
type() |
<type 'instance'> |
class类 |
__class__ |
class类 | class类 |
__slots__ |
不支持 | 支持 |
__getattribute__ |
不支持 | 支持 |
相同父类构造函数 | 重复执行多次 | 只执行一次 |
基类搜索顺序 | 深度优先 | 广度优先 |
类方法
一个类在使用时,需要先实例化,再初始化
__new__
该方法是一个实例化方法(静态方法,因为所有新式类都继承object类,而object类中该方法设置为静态方法)
一个对象实例化时调用的第一个方法;
-
返回创建的实例
-
当有父类时先执行父类的
new
-
不常用,但当继承一个不可改变的类型比如tuple 或 string时,一般返回实例化对象,最后会调用
__init__
,除非重写 -
如果返回的不是该类的实例化对象,则不执行__init__方法
1 | def __new__(cls, *args, **kwargs): |
__init__
初始化方法,构造函数被调用时任何参数都传递给他;
无返回值
def __init__(self, *args, **kwargs):pass
__call__
让类的实例对象可以象函数一样调用
无返回值
def __call__(self, *args, **kwargs):pass
__del__
相当于析构函数
当一个对象在删除的时候进行清理工作,但当解释器退出时,如对象还在,不保证执行
无返回值
def __del__(self):pass
__repr__
当对象要输出时,用来整理其属性及方法为可输出的格式
无返回值
def __repr__(self):pass
__str__
可读性更好的obj==eval(repr(obj))的
无返回值
def __str__(self):pass
__dict__
__dict__
好像是python3之后就没了
无返回值
def __dict__(self):pass
__setattr__
添加属性,并赋值
无返回值
def __setattr__(self, key, value):pass
__super__
super(B, self)
首先找到B的父类A,然后把B的对象self转换为A的对象(通过某种方式),然后“被转换”的A对象调用自己的__init__;
无返回值
def __super__(self):pass
__getattr__
只有当__getattribute__抛出AttributeError时才调用
无返回值
def __setattr__(self, name):pass
__getattribute__
这个方法很重要,会用于属性访问、super、类继承等
访问某个属性时,无条件默认调用,找不到时会抛出AttributeError提示找不到这个属性;
为了避免无限递归,应该把获取属性的方法指向其父类,即
super().__getattribute__(self, name)
def __getattribute__(self, name):pass
类属性
不论所属类是否实例化都会执行,使用时作为类的静态变量
__slots__
用于限定属性,即外部能访问的属性
__slots__ = ['var', ...]
__doc__
帮助信息
__name__
类型名称
__module__
所在模块
__class__
类型
__bases__
所继承的基类
__dict__
存储所有类型成员
key是属性名,value为属性值
实例的__dict__只存储与该实例相关的实例属性,即实例属性
类的__dict__存储所有实例变量共享的变量和函数,并不包含父类的属性
类的__dict__是一个只读,对象的__dict__是一个一般的;
1 | class C(): |
对象属性访问顺序
通过
__getattribute__
访问
- 实例属性
- 类属性
- 父类属性
__getattr__()
在每个层级访问时数据描述符优先于dict,而dict查找优先于非数据描述符;
这里请参考python 描述符
私有变量
-
以两个或以上下划线字符开头且没有以两个或以上下划线结尾的变量当作私有变量
-
私有变量会在代码生成之前被转换为长格式(变为公有),转换机制为:
在变量前端插入类名,再在前端加入一个下划线字符。这就是所谓的私有变量轧压(Private name mangling)
1 | class Person(): |