
我在构造一个自定义迭代器 Test 类的时候发现一个奇特的现象,Test 类并没有继承自 Iterable,只是实现了__iter__和__next__函数。
然而创建的对象却可以判定是 Iterable 类型
class TestIterator(): def __init__(self, n): ... def __iter__(self): return self def __next__(self): ... t1 = Test() isinstance(t1, Iterable) #返回 True !!! 然后我又创建了一组普通的类测试,发现又不行了:
class A: def do1(self): print('A do1') class B(A): def do2(self): print('B do2') class X: def do1(self): print('X do1') a1 = A() b1 = B() x1 = X() isinstance(b1, A) #True isinstance(x1, A) #False ??? 1 fengjianxinghun May 14, 2021 |
2 knightdf May 14, 2021 建议你看看 collections.abc.Iterable 的文档 |
3 geelaw May 14, 2021 答案是因为 Iterable 是抽象基类 (abstract base class),但 A 不是。isinstance 对于抽象基类 (ABC) 有特殊的规则。 https://docs.python.org/3/library/functions.html#isinstance 当 object 是 classinfo 或它(直接、间接、虚拟)子类的实例时,返回 True 。 点击“虚拟”,可以看到 https://docs.python.org/3/glossary.html#term-abstract-base-class ABC 引入虚拟子类虽然不继承,但 isinstance()、issubclass() 仍然识别为子类。 |
4 abersheeran May 14, 2021 https://docs.python.org/3/reference/datamodel.html?highlight=instancecheck#class.__instancecheck__ 为你的 A 实现一个 __instancecheck__ 用以检查 do1 是否存在就行。 如果你觉得手工穷举检查麻烦,可以使用 https://docs.python.org/zh-cn/3/library/typing.html#typing.runtime_checkable |