本帖最后由 Ensoleile 于 2023-1-13 00:22 编辑
代偿#__contains__()主要用于实现成员关系的检测,对应in、not in
class C:
def __init__(self, data):
self.data = data
def __contains__(self, item):
print('hello')
return item in self.data
c =C([1, 2, 3, 4, 5])
print(3 in c)
#hello
#True
#[1, 2, 3, 4, 5]对应self.data,3对应__contains__()魔法方法中的item
#__contains__()代偿 P189 -> __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])
print(3 in c)
#iter->next->next->next->True
#首先调用iter将列表变为迭代器,再按个使用next拿出数据比较,直到找到的时候返回True
print(6 in c)
#iter->next->next->next->next->next->next->False
class C:
def __init__(self, data):
self.data = data
def __getitem__(self, item):# item对应的不是3 in c中的3,而是迭代时的0,1,2....
print('getitem', end='->')
return self.data[item]
c = C([1, 2, 3, 4, 5])
print(3 in c)
# getitem->getitem->getitem->True
print(6 in c)
# getitem->getitem->getitem->getitem->getitem->getitem->False
#__bool__():布尔测试 -> __len__()
class D:
def __bool__(self):
print('bool')
return True
d = D()
print(bool(d))
# bool
# True
class D:
def __init__(self, data):
self.data = data
def __len__(self):
print('len')
return len(self.data)
d = D('fishc')
print(bool(d))
# len
# True 长度非零则直接返回True
d = D([])
print(bool(d))
# len
# False
#跟比较运算相关的魔法方法:P189 < <= > >= == !=
class S(str):
def __lt__(self, other):
return len(self) < len(other)
def __gt__(self, other):
return len(self) > len(other)
def __eq__(self, other):
return len(self) == len(other)
s1 = S('FishC')
s2 = S('fishc')
print(s1 < s2)#False
print(s1 > s2)#False
print(s1 == s2)#True
print(s1 != s2)#True
#__eq__()只会拦截等值判断(==),返回长度比较结果,不会拦截不等值判断(!=),故不等于号两边比较的依然是字符串ASCII码是否相同
print(s1 <= s2)#True
print(s1 >= s2)#False
#如果不想让某个魔法方法生效,可以直接将其赋值为None
class S(str):
def __lt__(self, other):
return len(self) < len(other)
def __gt__(self, other):
return len(self) > len(other)
def __eq__(self, other):
return len(self) == len(other)
__le__ = None
__ge__ = None
__ne__ = None
s1 = S('FishC')
s2 = S('fishc')
try:
s1 != s2
except TypeError as e:
print(e)
#'NoneType' object is not callable
#这种做法也适用与代偿实现,定义第一个魔法方法为None后可以使代偿不实现
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
__contains__ = None#__contains__ -> __iter__() + __next__() -> __getitem__()
c = C([1, 2, 3, 4, 5])
try:
print(3 in c)
except TypeError as e:
print(e)
#'C' object is not a container
|