对于__contains__(self,item),主要用于实现成员关系的检测,其对应的运算符是in和not in
class C:
def __init__(self,data):
self.data = data
def __contains__(self,item):
print("检测到 in or not in 操作!")
return item in self.data # 检索item是否存在
c = C([1,2,3,4,5]) # 向实例对象中输入一个列表
3 in c # 判断 3 是否 在实例对象c中
# 检测到 in or not in 操作!
# True
只是简单的判断item是否包含在self.data中,是就返回true,不是就返回false。
所谓代偿,就是换另一种方式来实现未实现的功能。当程序没有找到__contains__()方法的时候,会去寻找__iter__()和__next__()方法,如果__iter__()和__next__()方法也没有找到,会去寻找__getitem__()方法。
class C:
def __init__(self,data):
self.data = data
def __iter__(self):
print("iter",end='->')
self.i = 0
return self # 返回迭代器
def __next__(self):
print("next",end='->')
if self.i == len(self.data): # 等到下标值与对应数据长度相等时,结束寻找
raise StopIteration
item = self.data[self.i]
self.i += 1
return item
c = C([1,2,3,4,5])
3 in c
# iter->next->next->next->True
6 in c
# iter->next->next->next->next->next->next->False
上述例子是将列表里面的数据一个一个的返回,直到找到需要的数据时,结束寻找。
# iter->next->next->next->True True是3 in c 的结果,会拿3 和return的item进行比较运算。
__bool__(),对于__bool__()魔法方法,在进行布尔测试的时候会触发
class D:
def __bool__(self):
print("boy jiji boy~")
return True #默认一直返回Ture
d = D()
bool(d)
# boy jiji boy~
# True
如果找不到__bool__(),Python会去寻找__len__()这个魔法方法。
class D:
def __init__(self,data):
self.data = data
def __len__(self):
print("len")
return len(self.data)
d = D("Python")
bool(d)
# len
# True
对于上述代码返回的是Ture而不是具体的字符串长度是因为这时进行的是布尔运算,只是触发了__len__(),所以结果仍然是返回True或者False。
__lt__(self,other) | < |
__le__(self,other) | <= |
__gt__(self,other) | > |
__ge__(self,other) | >= |
__eq__(self,other) | == |
__ne__(self,other) | != |
这些方法主要作用于:人们一般都会认为比较字符串比较的是字符串的长度,而不是比较每个字符串的编码值大小,但事实不是这样,结果是恰恰相反的。
class S(str):
def __lt__(self,other):
return len(self)len(other)
def __eq__(self,other):
return len(self)==len(other)
s1 = S("Python")
s2 = S("python")
# 下面比较的不是编码值的大小,而是比较的字符串长度
s1s2
# False
s1==s2
# True
s1!=s2
# True
不要以为s1 == s2的结果是ture,s1 != s2的结果就是false了,因为我们没有定义__ne__()方法,所以进行的仍然是编码值得比较,从而说明这些魔法方法只有在定义(我们自己定义的)的时候才会起作用。
像是刚才那样s1!=s2的结果是ture,是因为去访问没有定义的__len__()方法去了,如果我们不想出现这样的情况,可以使用None来修饰。
class S(str):
def __lt__(self,other):
return len(self)len(other)
def __eq__(self,other):
return len(self)==len(other)
__ne__ = None
s1 = S("Python")
s2 = S("python")
s1!=s2
'''
Traceback (most recent call last):
File "", line 1, in
s1!=s2
TypeError: 'NoneType' object is not callable
'''
这时候再去执行s1!=s2测试,就会出现错误信息。同样的,像之前提到的一些魔法方法也可以用None进行修饰。