从Python中的基类导入子类

时间:2011-11-30 09:43:47

标签: python inheritance import subclass base

我有一个基类,它有一个创建子类实例的方法,该子类的实例与输入字符串相同。

之前通过将子类和基类放在同一个文件中,并执行类似globals()[name]的操作。

但是,现在,我已将子类拆分为其他文件。它们每个都在顶部有一个import base语句,所以我不能简单地在我的基类中导入子类,或者有一个循环导入链。

有没有解决方法呢?

base.py

from basefactory import BaseFactory
class Base:
    def __init__(self, arg1, arg2):
        ...
    def resolve(self, element):
        className = typing.getClassName(element)
        return BaseFactory.getInstance(className, element, self)

basefactory.py

from file1 import *
from file2 import *
...
class BaseFactory:
    @staticmethod
    def getInstance(name, arg1, arg2):
       subclass = globals()[name]
       return subclass(arg1, arg2)

file1.py

from base import Base

class subclass1(Base):
    def foo(self):
        return self.arg1

3 个答案:

答案 0 :(得分:5)

根据我的理解,你有:

  1. 基类
  2. 基类
  3. 中的一系列派生类
  4. 基类中的工厂方法,用于实例化正确类型的派生类
  5. 派生类已拆分为文件,它们依赖于基类,但基类中的工厂方法取决于派生类
  6. 一种解决方案是为工厂方法创建一个单独的函数/类,并将其放在与基类不同的文件中。此文件可以导入基类和派生类的所有文件,而不使用循环引用。

    例如:

    # base.py:
    class baseClass():
       def __init__(self):
          self.name = "Base"
    
    # sub1.py:
    from base import baseClass
    class sub1Class(baseClass):
       def __init__(self):
          self.name = "sub1"
    
    # sub2.py:
    from base import baseClass
    class sub2Class(baseClass):
       def __init__(self):
          self.name = "sub2"
    
    # factory.py:
    from sub1 import sub1Class
    from sub2 import sub2Class # should not create an error
    mapping = {'sub1': sub1Class, 'sub2': sub2Class}
    
    def create(baseType):
      return mapping[baseType]
    

    实际上,更好的方法可能是使用type

    type(name, bases, dict)返回一个新类型对象。这实际上是类语句的动态形式。名称字符串是类名,并成为__name__属性;基元元组列出基类并成为__bases__属性; dict字典是包含类体定义的命名空间,并成为__dict__属性。例如,以下两个语句创建相同的类型对象:

    >>> class X(object):
    ...     a = 1
    ...
    >>> X = type('X', (object,), dict(a=1))
    

    为什么不将决心转移到经理类?查看Class factory in Python中的域类。我不确定是否需要解析...您可以直接从self.__class__.__name__获取类名,并使用type()isinstance()之类的python函数来检查它们是否是特定类型

    同时退房:
    Can you use a string to instantiate a class in python?
    Does python have an equivalent to Java Class.forName()?

答案 1 :(得分:4)

您可以将失败的import语句移动到创建子类对象的方法。

答案 2 :(得分:0)

我不知道我是否理解你, 如果你需要子类,为什么要把子类带出类?然后让我们在课堂内,无论你需要什么,你都可以from class import subclass