Python类工厂引用基类的问题?

发布于 2024-11-01 08:49:25 字数 1480 浏览 2 评论 0原文

我最近遇到了一个 Python 类工厂实现,它非常适合我正在解决的问题。唯一的区别是我希望将基类和子类放在不同的包中。

然而,当我尝试这样做时,每当我尝试加载基类时都会遇到问题。

结构:

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..")

subclasses/__init__.py

__all__=['SubClass']

subclasses/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 模块时,才会出现问题。

有什么想法吗?

I recently came across a Python class factory implementation that fit a problem I am working on really well. The only difference is that I wanted have the base and sub classes in different packages.

When I try to do this, however, I run into a problem whenever I try to load the base class.

Structure:

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..")

subclasses/__init__.py

__all__=['SubClass']

subclasses/SubClass.py

from BaseClass import BaseClass
class SubClassA(BaseClass):
    def __init__(self):
        print('Instantiating SubClassA')

When I try to import BaseClass though I get the following error:

       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

I also tried using "import BaseClass" and then subclassing "BaseClass.BaseClass" but that resulted in a different error:

      1 import BaseClass
----> 2 class SubClassA(BaseClass.BaseClass):
      3     def __init__(self):
      4         print('Instantiating SubClassA')

AttributeError: 'module' object has no attribute 'BaseClass'

Finally, If I just try to create the subclass directory there is no problem. It is only when I try to import the BaseClass module that things go wrong.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伪心 2024-11-08 08:49:25

一些实验似乎表明问题出在导入递归上。在 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 ()

Some experimenting appears to show that the problem is import recursion. Making the import statement in BaseClass.py conditional solved the problem for my tests:

if __name__ == '__main__':
    from subclasses import *

prevents the recursion and python appears satisfied with this.

[EDIT]

A better solution is to have the NewClass method in a separate file:

something.py

from BaseClass import BaseClass
from subclasses import *

def NewClass():
    """Map Factory"""
    for cls in BaseClass.__subclasses__():
        print ("checking class...")

NewClass ()
捎一片雪花 2024-11-08 08:49:25

如果没有更多信息,您的模块 BaseClass 似乎并不直接位于 python 路径上。 BaseClass能够找到子类,因为它们存在于BaseClass正下方的目录中。反之则不然。

相对导入应该可以解决此问题。

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 能够在事先不知道它们的情况下使用它们。

Without more information, it appears that your module BaseClass is not directly on the python path. BaseClass is able to find the sub classes, because they exist in a directory directly below BaseClass. The converse is not true.

A relative import should fix this issue.

from .. BaseClass import BaseClass

The .. will go up a directory, and look there (kind of like file paths). The alternative is to put BaseClass directly on the PYTHONPATH.

Having two different modules depending on each other sounds like not so great an idea though to be honest. Better off having the subclasses register with the BaseClass.

Edit:

What I meant by 'registering with the base class' is something like the following:'

# baseclass.py
subclasses = []
def register(cls):
    subclasses.append(cls)


# subclass.py
class SubClassA(BaseClass):
    ...

baseclass.register(SubClassA)

Now BaseClass doesn't need to know about all the different subclasses. They register to be used, and the BaseClass is able to use them without knowing about them before hand.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文