Python weakref.proxy对象被认为是可迭代的



我发现了以下内容(使用Python 3.8.3(:

from collections.abc import Iterable
from weakref import proxy
class Dummy:
pass
isinstance(d := Dummy, Iterable)
# False (as expected)
isinstance(p := proxy(d), Iterable)
# True (why?!)
for _ in p:
# raises TypeError
pass

代理对象如何通过可迭代测试?

它提供__iter__,以防底层类型提供它。__iter__必须在类型上实现,而不是在实例上实现,因此它不能有条件地定义__iter__而不拆分成许多不同的类,而不仅仅是一个proxy类。

不幸的是,Iterable测试只是检查类是否定义了__iter__,而不是它是否工作,并且proxy不知道它是否真的工作,而不调用封装类的__iter__。如果您想检查可迭代性,只需对其进行迭代,如果失败,则捕获TypeError。如果你不能立即迭代它,而它受到检查时间/使用时间竞赛条件的限制,你可以编写自己的简单测试程序,涵盖它是否真的可以迭代:

def is_iterable(maybeiter):
try:
iter(maybeiter)
except TypeError:
return False
else:
return True

最新更新