我最近遇到了一个Python class factory implementation符合我正在努力解决的问题。唯一的区别是我希望在不同的包中有基类和子类。
但是,当我尝试这样做时,每当我尝试加载基类时都会遇到问题。
结构:
BaseClass.py
from subclasses import *
def NewClass():
"""Map Factory"""
for cls in BaseClass.__subclasses__():
print "checking class..."
class BaseClass(object):
def __init__(self):
print("Building an abstract BaseMap class..")
子类/ __初始化__。PY
__all__=['SubClass']
子类/ SubClass.py
from BaseClass import BaseClass
class SubClassA(BaseClass):
def __init__(self):
print('Instantiating SubClassA')
当我尝试导入BaseClass时,我收到以下错误:
1 #import BaseClass ----> 2 from BaseClass import BaseClass 3 class SubClassA(BaseClass): 4 def __init__(self): 5 print('Instantiating SubClassA') ImportError: cannot import name BaseClass
我也尝试使用“import BaseClass”然后继承“BaseClass.BaseClass”,但这导致了一个不同的错误:
1 import BaseClass ----> 2 class SubClassA(BaseClass.BaseClass): 3 def __init__(self): 4 print('Instantiating SubClassA') AttributeError: 'module' object has no attribute 'BaseClass'
最后,如果我只是尝试创建子类目录,则没有问题。只有当我尝试导入BaseClass模块时才会出错。
有什么想法吗?
答案 0 :(得分:2)
某些实验似乎表明问题是导入递归。在BaseClass.py条件中创建import语句解决了我的测试问题:
if __name__ == '__main__':
from subclasses import *
阻止递归,python似乎对此感到满意。
[编辑]
更好的解决方案是将NewClass方法放在一个单独的文件中:
<强> something.py 强>
from BaseClass import BaseClass
from subclasses import *
def NewClass():
"""Map Factory"""
for cls in BaseClass.__subclasses__():
print ("checking class...")
NewClass ()
答案 1 :(得分:1)
如果没有更多信息,您的模块BaseClass
似乎不直接位于python路径上。 BaseClass能够找到子类,因为它们存在于BaseClass正下方的目录中。相反的情况并非如此。
relative import应解决此问题。
from .. BaseClass import BaseClass
..
将上一个目录,并查看那里(有点像文件路径)。另一种方法是将BaseClass直接放在PYTHONPATH上。
虽然说实话,但是两个不同的模块相互依赖听起来并不是一个好主意。最好让子类注册BaseClass。
编辑:
“注册基类”的含义如下:'
# baseclass.py
subclasses = []
def register(cls):
subclasses.append(cls)
# subclass.py
class SubClassA(BaseClass):
...
baseclass.register(SubClassA)
现在,BaseClass不需要知道所有不同的子类。它们注册使用,而BaseClass能够在不事先了解它们的情况下使用它们。