Python类工厂问题引用基类?

时间:2011-04-16 11:27:51

标签: python class import factory importerror

我最近遇到了一个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模块时才会出错。

有什么想法吗?

2 个答案:

答案 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能够在不事先了解它们的情况下使用它们。