issubclass()在从不同路径导入的同一类上返回False [英] issubclass() returns False on the same class imported from different paths
问题描述
目的是实现某种插件框架,其中插件是相同基类(即A)的子类(即B)。 $ p
$ b
The intention was to implement some sort of plugin framework, where plugins are subclasses (i.e. B) of the same base class (i.e. A). The base class is loaded with standard import, whereas subclasses are loaded with imp.load_module() from the path of a well-known package (i.e. pkg).
pkg/
__init__.py
mod1.py
class A
mod2.py
class B(pkg.mod1.A)
这对于 real 子类,即
# test_1.py
import pkg
from pkg import mod1
import imp
tup = imp.find_module('mod2', pkg.__path__)
mod2 = imp.load_module('mod2', tup[0], tup[1], tup[2])
print(issubclass(mod2.B, mod1.A)) # True
但是问题出在测试基类本身时,
But the problem came when testing the base class itself,
# test_2.py
import pkg
from pkg import mod1
import imp
tup = imp.find_module('mod1', pkg.__path__)
mod0 = imp.load_module('mod1', tup[0], tup[1], tup[2])
print(issubclass(mod0.A, mod1.A)) # False
但是mod0.A和mod1.A实际上是同一文件(pkg / mod1.py)中的同一类。
But mod0.A and mod1.A are actually the same class from the same file (pkg/mod1.py).
出现此问题在python 2.7和3.2中。
This issue appears in both python 2.7 and 3.2.
现在问题是双重的,a)是预期功能还是issubclass()的错误,以及b)如何
Now the question is two-fold, a) Is it an expected feature or a bug of issubclass(), and b) How to get rid of this without changing contents of pkg?
推荐答案
他们不是同一类。它们是用相同的代码创建的,但是由于您两次执行了该代码(一次在导入中,一次在load_module中),您将获得两个不同的类对象。 issubclass
正在比较类对象的标识,但它们是不同的。
They aren't the same class. They were created with the same code, but since you executed that code twice (once in the import and once in load_module) you get two different class objects. issubclass
is comparing the identities of the class objects and they're different.
编辑:因为您不能依靠 issubclass
,一种可能的选择是在基类上创建一个唯一的属性,该属性将由派生类继承。该属性也将存在于类的副本中。然后可以测试该属性。
since you can't rely on issubclass
, one possible alternative is to create a unique attribute on the base class that will be inherited by the derived classes. This attribute will exist on copies of the class as well. You can then test for the attribute.
class A:
isA = True
class B(A):
pass
class C:
pass
def isA(aclass):
try:
return aclass.isA
except AttributeError:
return False
print isA(A)
True
print isA(B)
True
print isA(C)
False
这篇关于issubclass()在从不同路径导入的同一类上返回False的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!