我试图弄清楚为什么issubclass()
的行为会根据类的导入方式而发生变化。
我有以下设置
proj
|_pkg
|_ __init__.py
|_ base.py
|_ child.py
base.py有
class Base(object):
pass
child.py有
from base import Base
class Child(Base):
pass
然后我在shell中执行以下操作:
$export PYTHONPATH='/tmp/proj'
$ipython
In [1]: from pkg.base import Base as Base1
In [2]: from base import Base as Base2
In [3]: from pkg.child import Child as Child1
In [4]: from child import Child as Child2
In [5]: issubclass(Child1, Base1)
Out[5]: True # Makes Sense
In [6]: issubclass(Child1, Base2)
Out[6]: False # Confused. Why would this be False.
In [7]: issubclass(Child2, Base1)
Out[7]: False # Confused. Why would this be False.
In [8]: issubclass(Child2, Base2)
Out[8]: True
我对In [6]和[7]中发生的事情感到困惑。我希望那些也是True
。
答案 0 :(得分:1)
经过一番挖掘后找到答案 - http://python-notes.curiousefficiency.org/en/latest/python_concepts/import_traps.html#the-double-import-trap
这个下一个陷阱存在于所有当前版本的Python中,包括 3.3,可以总结为以下一般准则:“永远不要直接添加包目录,或包内的任何目录,直接 到Python路径“。
这是有问题的原因是该目录中的每个模块 现在可以通过两个不同的名称访问:作为顶部 level模块(因为目录在sys.path上)和子模块 包(如果包含包的更高级目录) 本身也在sys.path上。
作为一个例子,Django(包括版本1.3)曾经是 为特定地点设置确切的这种情况 应用程序 - 应用程序最终可以作为两个应用程序访问 和site.app在模块名称空间中,这些实际上是两个 该模块的不同副本。