以这种方式使用issubclass时为什么会得到False?

时间:2016-07-20 08:47:38

标签: python python-3.x

结构:

package/
    m1.py
    m2.py

m1.py

class A:
    pass


if __name__ == '__main__':
    from m2 import B

    print(issubclass(B, A))

m2.py

from m1 import A


class B(A):
    pass

我现在不知道为什么我会弄错,而我认为当我运行m1.py时它显然是正确的。我的python版本是python3.5.2。

4 个答案:

答案 0 :(得分:2)

您必须从A派生课程object才能让issubclass完成工作:

isinstance() and issubclass() behavior differently

class A(object): ...

这是python cli的一个例子:

>>> class A(object): pass
>>> class B(A): pass
>>> issubclass(B,A)
True

答案 1 :(得分:1)

您创建了两个派生自同一个类的类对象。即:类代码执行两次,从而产生2个对象。那些不一样。示例:查看下面print语句的输出

# m2.py
from m1 import A

class B(A):
    pass

print(A)

# m1.py
class A:
    pass

if __name__ == '__main__':
    from m2 import B
    print(A)
    print(issubclass(B, A))

# Output
#<class 'm1.A'>
#<class '__main__.A'>
#False

另外:有关详细信息,请参阅this answer

答案 2 :(得分:1)

欢迎来到模块和命名空间的世界!

以下是发生的事情:

在模块m2中,从模块m1导入A.因此,您创建了一个类m2.A作为对类m1.A的引用。它恰好与__main__.A具有相同的定义,但它们是不同的对象,因为主模块名为__main__而不是m1。然后在模块__main__中创建一个类__main__.B作为对类m2.B的引用

为了更好地理解这里发生的事情,我在m1中添加了一些代码:

...
print(issubclass(B, A))

import m1
import m2
print(A == m1.A, m1.A == m2.A)
print(B == m2.B)
print(issubclass(B, m2.A), issubclass(B, m1.A))

输出结果为:

False
False True
True
True True

证明B确实是m1.A的子类,而不是__main.A的子类。

答案 3 :(得分:0)

在m1.py中,您提供的是A类,在m2.py中,您的是导入A​​的类。即使它是从m1.py导入的,也不是同一对象。您实际上从不会导入仅导入代码的确切对象,而是创建了一个单独的对象。因此,您不必期望仅导入两个单独的A()类代码块,而是希望它们成为彼此的子类,因为它们具有相同的名称,而不是导入A类。您不是在检查类的名称是否与您在检查该类是否是实际类对象的子类(而不仅仅是名称的文本)相同。

这与从第三个完全不同的模块中导入A类没有什么不同,因为您只是导入代码而不是对象。