2.特殊方法
python解释器碰到特殊的句法时,会使用特殊方法去激活一些基本的对象操作,这些特殊方法的名字以两个下划线开头,以两个下划线结尾(例如__getitem__)。比如obj[key]背后就是__getitem__()方法,为了能求得my_collection[key]的值,解释器实际上会调用mycollection.__getitem__(key)。这些特殊方法名能让你自己的对象实现和支持以下的语言框架,并与之交互:
迭代
集合类
属性访问
运算符重载
函数和方法的调用
字符串表示形式和格式化(基础方法)
管理上下文(用with块)
序列化
对象的创建和销毁
2.1 python命名规则
-
"单下划线"开始的成员变量叫做保护变量,意思是只有类对象和子类对象自己能访问到这些变量
-
”双下划线“开始是私有成员,意思是只有类对象自己能访问,连子对象也不能访问到这个数据
-
”双下划线“开始,”双下划线“结束的函数代表python里特殊方法专用的标识。
2.2 类的基础方法
目的 | 代码 | python实际调用 |
---|---|---|
初始化一个实例 | x = Myclass() | x.__init__() |
字符串的“官方”表现形式 | repr() | x.__repr__() |
字符串的“非正式”值 | str() | x.__str__() |
字节数组的“非正式“值 | bytes(x) | x.__bytes__() |
格式化字符串的值 | format(x,format_spec) | x.__format__(format_spec) |
2.3行为方式与迭代器类似的类
目的 | 代码 | python实际调用 |
---|---|---|
遍历某个序列 | iter(seq) | seq.__iter__() |
从迭代器中获取下一个值 | next(seq) | seq.__next__() |
按逆序创建一个迭代器 | reversed(seq) | seq.__reversed__() |
2.4 集合类
2.4.1 行为方式与序列类似的类
目的 | 代码 | python实际调用 |
---|---|---|
序列的长度 | len(seq) | seq.__len__() |
了解某序列是否包含特定的方法 | x in seq | seq.__contain__(x) |
2.4.2 行为方式与字典类似的类
目的 | 代码 | 实际调用 |
---|---|---|
通过键来获取值 | x[key] | x.__getitem__(key) |
通过键来设置值 | x[key] = value | x.__setitem__(key,value) |
删除一个键值对 | del x[key] | x.__delitem__(key) |
为缺失提供默认值 | x[nonexistent_key] | x.__missing__(nenexistent_key) |
2.4 属性访问
目的 | 代码 | python实际调用 |
---|---|---|
获取一个计算属性 | x.my_property | x.__getattribute__('my_property') |
获取一个计算属性(后备) | x.my_property | x.__getattr__('my_property') |
设置某属性 | x.my_property = value | x.__setattr__('my_property,value') |
删除某属性 | del x.my_property | x.__delattr__('my_property') |
列出所有属性和方法 | dir(x) | x.__dir__() |
2.5 运算符重载
2.5.1比较运算符
目的 | 代码 | python实际调用 |
---|---|---|
相等 | x == y | x.__eq__(y) |
不相等 | x != y | x.__ne__(y) |
小于 | x < y | x.__lt__(y) |
小于或等于 | x <= y | x.__le__(y) |
大于 | x > y | x.__gt__(y) |
大于或等于 | x >= y | x.__ge__(y) |
布尔上下文环境中的真值 | if x: | x.__bool__() |
2.5.2 计算运算符
目的 | 代码 | python实际调用 |
---|---|---|
加法或拼接 | + | x.__add__(y) |
减法 | - | x.__sub__(y) |
乘法或重复复制 | × | x.__mul__(y) |
除法 | / | x.__truediv__(y) |
整除 | // | x.__floordiv__(y) |
取模 | % | x.__mod__(y) |
返回由整除的商和模数组成的元祖 | divmod() | x.__divmod__(y) |
取幂 | **,pow() | x.__pow__(y) |
矩阵乘法 | @ | x.__matmul__(y) |
2.6 行为方式与函数类似的类
目的 | 代码 | python实际调用 |
---|---|---|
像调用函数一样”调用“一个实例 | my_instance() | my_instance.__call__() |
2.7 可在with语块中使用的类
目的 | 代码 | python实际调用 |
---|---|---|
在进入with语块时进行一些特别操作 | with x: | x.__enter__() |
在退出with语块时进行一些特别操作 | with x: | x.__exit_|_() |
-
__exit__()方法将总是被调用,哪怕是在with语块中引发了例外。实际上,如果引发了例外,该例外信息将会被传递给__exit__()方法。
2.8 可序列化的类
目的 | 代码 | python实际调用 |
---|---|---|
自定义对象的复制 | copy.copy(x) | x.__copy__() |
自定义对象的深度复制 | copy.deepcopy(x) | x.__deepcopy__() |
在picking之前获取对象的状态 | pickle.dump(x,file) | x.__getstate__() |
序列化某对象 | pickle.dump(x,file) | x.__reduce__() |
序列化某对象(新picking协议) | pickle.dum(x,file,protoco_version) | x.__reduce_ex__(protocol_version) |
控制unpicking过程中对象的创建方式 | x = pickle.load(file) | x.__getnewargs__() |
在unpicking之后还原对象的状态 | x = pickle.load(file) | x.__setstate__() |
2.9 类的控制
目的 | 代码 | python实际调用 |
---|---|---|
类构造器 | x.Myclass() | x.__new__() |
类析构器 | del x | x.__del__() |
只定义特定集合的某些属性 | x.__slots__() | |
自定义散列值 | hash(x) | x.__hash__() |
获取某个属性的值 | x.color | type(x).__dict__['color'].__get__(x,type(x)) |
设置某个属性的值 | x.color = 'PapayWhip' | type(x).__dict__['color'].__set__(x,'PapayWhip') |
删除某个属性 | del x.color | type(x).__dict__['color'].__del__(x) |
控制某个对象是否是该对象的实例 | isinstance(x,MyClass) | Myclass.__instancecheck__(x) |
控制某个类是否是该类的子类 | insubclass(c,MyClass) | Myclass.__subclasscheck__(c) |
控制某个类是否是该抽象基类的子类 | issubclass(c,MyABC) | MyABC.__subclasshook__(c) |