特殊方法简介
方法
描述
__init__()
构造函数
__len__()
重载len(),例如:len(obj)
__getitem__()
重载[](读操作),例如:obj[0]
__setitem__()
重载[](写操作),例如:obj[0] = 123
__str__()
重载 str(),例如:str(obj)
__repr__()
重载 repr(),例如:repr(obj),遇到字符串格式化 %r 时会调用它
__abs__()
重载 abs(),例如:abs(obj)
__bool__()
重载 bool(),例如:bool(obj)
__add__()
重载加法操作符+,例如:obj1 + obj2
__mul__()
重载乘法操作符*,例如:obj1 * 123
...
...
更多的特殊方法请参考本文末尾“特殊方法列表”。
特殊方法示例
__init__()
class Foo:
def __init__(self):
print("Foo::__init__() is called")
foo = Foo() # Foo::__init__() is called
__len__()、__getitem__()、__setitem__()
class Foo:
def __init__(self):
self.data = []
def __len__(self):
print("Foo::__len__() is called")
return len(self.data)
def __getitem__(self, index):
print("Foo::__getitem__(%d) is called" % index)
return self.data[index]
def __setitem__(self, index, value):
print("Foo::__setitem__(%d,%r) is called" % (index, value))
if len(self.data) > index:
self.data[index] = value
else:
self.data.append(value)
foo = Foo()
foo[0] = 123 # Foo::__setitem__(0,123) is called
foo[1] = "abcd" # Foo::__setitem__(1,'abcd') is called
print(len(foo)) # Foo::__len__() is called\n2
foo[0] # Foo::__getitem__(0) is called
__str__()、__repr__()
__str__() 与 __repr__() 类似,都是将对象转换为字符串,区别:
__str__() 倾向于返回可读性更高的字符串(readable, pretty print);
__repr__() 倾向于返回准确、无歧义的字符串(unambiguous),例如:"%r, %r" % (123, "123") 结果是"123, '123'",同样都是123,前者是数字,后者是字符串,必须准确表达;
当 __str__() 没有被定义但是定义了 __repr__() 时,__repr__() 会被 str() 借用,反过来则不会。
示例:
class A:
pass
a = A() # 当 __repr__() 和 __str__() 都没有定义,使用默认输出
print(str(a)) # <__main__.a instance at>
print(repr(a)) # <__main__.a instance at>
print("%r" % a) # <__main__.a instance at>
class B:
def __repr__(self):
return "B::__repr__"
b = B() # 当定义了 __repr__() 但没有定义 __str__()
print(str(b)) # B::__repr__ # str() 会调用 __repr__()
print(repr(b)) # B::__repr__
print("%r" % b) # B::__repr__
class C:
def __str__(self):
return "C::__str__"
c = C() # 当定义了 __str__() 但没有定义 __repr__(),repr()不会调用 __str__()
print(str(c)) # C::__str__
print(repr(c)) # <__main__.c instance at>
print("%r" % c) # <__main__.c instance at>
class D:
def __repr__(self):
return "D::__repr__"
def __str__(self):
return "D::__str__"
d = D() # # 当 __repr__() 和 __str__() 都有定义,各自使用各自的
print(str(d)) # D::__str__
print(repr(d)) # D::__repr__
print("%r" % d) # D::__repr__
特殊方法列表
注:本小节中表格数据来自于《流畅的Python》。
跟运算符无关的特殊方法
类别
方法名
字符串 / 字节序列表示形式
__repr__、__str__、__format__、__bytes__
数值转换
__abs__、__bool__、__complex__、__int__、__float__、__hash__、__index__
集合模拟
__len__、__getitem__、__setitem__、__delitem__、__contains__
迭代枚举
__iter__、__reversed__、__next__
可调用模拟
__call__
上下文管理
__enter__、__exit__
实例创建和销毁
__new__、__init__、__del__
属性管理
__getattr__、__getattribute__、__setattr__、__delattr__、__dir__
属性描述符
__get__、__set__、__delete__
跟类相关的服务
__prepare__、__instancecheck__、__subclasscheck__
跟运算符相关的特殊方法
类别
方法名和对应的运算符
一元运算符
__neg__ -、__pos__ +、__abs__ abs()
比较运算符
__lt__ 、__ge__ >=
比较运算符
__lt__ 、__ge__ >=
算术运算符
__add__ +、__sub__ -、__mul__ *、__truediv__ /、__floordiv__ //、__mod__ %、__divmod__ divmod()、__pow__ ** 或pow()、__round__ round()
反向算术运算符
__radd__、__rsub__、__rmul__、__rtruediv__、__rfloordiv__、__rmod__、__rdivmod__、__rpow__
增量赋值算术运算符
__iadd__、__isub__、__imul__、__itruediv__、__ifloordiv__、__imod__、__ipow__
位运算符
__invert__ ~、__lshift__ <>、__and__ &、__or__ |、__xor__ ^
反向位运算符
__rlshift__、__rrshift__、__rand__、__rxor__、__ror__
增量赋值位运算符
__ilshift__、__irshift__、__iand__、__ixor__、__ior__