Python _ugetItem和in运算符导致奇怪的行为
如何解释以下行为:Python _ugetItem和in运算符导致奇怪的行为,python,python-3.x,Python,Python 3.x,如何解释以下行为: class Foo: def __getitem__(self, item): print("?") return 1 f = Foo() 1 in f # prints one ? and returns True 5 in f # prints ? forever until you raise a Keyboard Exception # Edit: eventually this fails with Overflo
class Foo:
def __getitem__(self, item):
print("?")
return 1
f = Foo()
1 in f # prints one ? and returns True
5 in f # prints ? forever until you raise a Keyboard Exception
# Edit: eventually this fails with OverflowError: iter index too large
如果一个对象没有
\uuuu包含
实现,中的会使用默认值,其基本工作原理如下:
def default__contains__(self, element):
for thing in self:
if thing == element:
return True
return False
def default__iter__(self):
i = 0
try:
while True:
yield self[i]
i += 1
except IndexError:
pass
如果一个对象没有\uuu iter\uuu
实现,那么for
的默认值基本上是这样的:
def default__contains__(self, element):
for thing in self:
if thing == element:
return True
return False
def default__iter__(self):
i = 0
try:
while True:
yield self[i]
i += 1
except IndexError:
pass
即使对象不打算成为序列,也会使用这些默认值
您的f
中的1和f
中的5测试正在使用
中的和
的的默认回退,从而导致观察到的行为
中的code>1会立即找到1
,但您的\uuu getitem\uuu
永远不会返回5
,因此f中的5将永远运行
(事实上,在Python的参考实现中,默认的\uuuuu iter\uuuuu
回退将索引存储在类型为Py\u ssize\u t
的C级变量中,因此如果您等待足够长的时间,该变量将最大化。如果您看到了这一点,您必须使用32位Python构建。计算机的存在时间还不够长,任何人都无法达到这一点。)在64位Python上。)关于OverflowerError,我在64位和32位上都运行了它,你是对的,我只在32位上看到了它。你知道解释这一点的文档吗?我想读一下为什么决定使用这个实现。@Matthew,还有上面的段落it@MatthewMoisen:这些默认值是 对于
中的和,在引入\uuuuuu iter\uuuuu和\uuuuuuu包含.之前。请参阅Python 1.4文档和。