Python weakref.proxy 对象被认为是可迭代的?
Python weakref.proxy object considered iterable?
我遇到了以下情况(使用 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__
而不分裂成许多不同的 class es,不只是一个 proxy
class.
不幸的是,Iterable
测试只是检查 class 是否定义了 __iter__
,而不是它是否有效,proxy
不知道它是否 really 无需调用包装的 class 的 __iter__
即可工作。如果您想检查可迭代性,只需对其进行迭代,如果失败则捕获 TypeError
。如果你不能立即迭代它,而它受制于 time-of-check/time-of-use 竞争条件,你可以编写自己的简单测试器来测试它是否可以 实际上 被迭代:
def is_iterable(maybeiter):
try:
iter(maybeiter)
except TypeError:
return False
else:
return True
我遇到了以下情况(使用 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__
而不分裂成许多不同的 class es,不只是一个 proxy
class.
不幸的是,Iterable
测试只是检查 class 是否定义了 __iter__
,而不是它是否有效,proxy
不知道它是否 really 无需调用包装的 class 的 __iter__
即可工作。如果您想检查可迭代性,只需对其进行迭代,如果失败则捕获 TypeError
。如果你不能立即迭代它,而它受制于 time-of-check/time-of-use 竞争条件,你可以编写自己的简单测试器来测试它是否可以 实际上 被迭代:
def is_iterable(maybeiter):
try:
iter(maybeiter)
except TypeError:
return False
else:
return True