马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本来魔法方法就够难啦, 还要加上代偿,真的很晕, 关于 in 语句 的代偿问题请教如下:
>>> class C:
def __init__(self, data):
self.data = data
self.num = 'agcd'
def __contains__(self, item):
print('hi')
return item in self.data
>>> c = C([1, 2, 3, 4, 5])
>>> 3 in c
hi
True
以上是正常调用代码:在使用in语句时(3 in c), 调用了魔法方法__contains__,其中 “ 3 对应参数 item”,“c 对应参数 self。
>>> class C:
def __init__(self, data):
self.data = data
self.num = 'agcd'
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
以上是代偿代码一:主要的疑惑是,在使用in语句时(3 in c) , ”3"对应的是哪个魔法方法的哪个参数,“c“ 对应的是哪个魔方方法的哪个参数
>>> class C:
def __init__(self, data):
self.data = data
def __getitem__(self, index):
print('Getitem', end=' ')
return self.data[index]
>>> c = C([1, 2, 3, 4, 5])
>>> 3 in c
Getitem Getitem Getitem True
以上是代偿代码一:同样的疑惑是,在使用in语句时(3 in c) , ”3"对应的是哪个魔法方法的哪个参数,“c“ 对应的是哪个魔方方法的哪个参数
在Python中,对于表达式 x in y ,解释器会先尝试调用 y 对象的 __contains__() 方法。如果 y 对象没有实现 __contains__() 方法,那么 Python 解释器会尝试使用其他方式来检查 x 是否在 y 中。
对于你的第二个和第三个例子, 3 in c 将尝试使用 __iter__() 或 __getitem__() 方法作为代偿(fallback)的方式,因为你的类 C 没有定义 __contains__() 方法。
在第二个例子中,Python将调用 c 的 __iter__() 方法来得到一个迭代器,然后通过调用这个迭代器的 __next__() 方法来遍历 c 中的所有元素,直到找到等于3的元素,或者所有元素都被遍历完。这里,"3"对应的就是每次调用 __next__() 方法返回的元素,"c"对应的是调用 __iter__() 方法的对象。
在第三个例子中,Python将反复调用 c 的 __getitem__() 方法,每次将递增的整数(从0开始)作为索引参数,直到找到等于3的元素,或者 __getitem__() 抛出 IndexError 异常。在这个例子中,"3"对应的是每次调用 __getitem__() 方法返回的元素,"c"对应的是调用 __getitem__() 方法的对象。
所以,虽然这两个例子中的 3 in c 看起来和第一个例子一样,但是它们的工作方式实际上是完全不同的,因为它们分别使用了不同的方法来查找元素3。
|