我发现了以下内容(使用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