请教关于in代偿的问题
本来魔法方法就够难啦, 还要加上代偿,真的很晕, 关于 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()
>>> 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 += 1
return item
>>> c = C()
>>> 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
>>> c = C()
>>> 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。 in语句的魔法方法是contains,它定义了对象是否包含某个元素的行为。例如,如果你写了3 in c,那么Python会调用c.__contains__(3)来检查c是否包含3。
如果对象没有定义contains方法,那么Python会尝试使用iter或者getitem方法来代偿2。这两个方法都可以让对象支持迭代,也就是说可以用for循环遍历对象的元素。例如,如果你写了3 in c,而c没有定义contains方法,但是定义了iter方法,那么Python会调用c.__iter__()来获取一个迭代器,并且用next()函数来逐个检查元素是否等于3。如果c没有定义iter方法,但是定义了getitem方法,那么Python会调用c.__getitem__(0),c.__getitem__(1)等等来逐个检查元素是否等于3。
所以,在你的例子中:
代偿代码一中,”3"对应的是next()函数返回的元素,“c“ 对应的是c.__iter__()返回的迭代器。
代偿代码二中,”3"对应的是c.__getitem__(index)返回的元素,“c“ 对应的是c.__getitem__(0),c.__getitem__(1)等等返回的索引。
希望这能帮助你理解in语句的魔法方法和代偿机制。
页:
[1]