在Python中从基类导入子类

在Python中从基类导入子类,python,inheritance,import,subclass,base,Python,Inheritance,Import,Subclass,Base,我有一个基类,它有一个方法,该方法创建一个子类的实例,该子类的调用与输入字符串相同 以前,通过将子类和基类放在同一个文件中,并执行类似于globals()[name]的操作,可以实现这一点 不过,现在我已经将子类拆分为其他文件。它们的顶部都有一个import base语句,因此我不能简单地导入基类中的子类,否则会有一个循环导入链 有什么解决办法吗 在base.py中: from basefactory import BaseFactory class Base: def __init__

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

以前,通过将子类和基类放在同一个文件中,并执行类似于
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)
from file1 import *
from file2 import *
...
class BaseFactory:
    @staticmethod
    def getInstance(name, arg1, arg2):
       subclass = globals()[name]
       return subclass(arg1, arg2)
from base import Base

class subclass1(Base):
    def foo(self):
        return self.arg1
basefactory.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)
from file1 import *
from file2 import *
...
class BaseFactory:
    @staticmethod
    def getInstance(name, arg1, arg2):
       subclass = globals()[name]
       return subclass(arg1, arg2)
from base import Base

class subclass1(Base):
    def foo(self):
        return self.arg1
文件1.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)
from file1 import *
from file2 import *
...
class BaseFactory:
    @staticmethod
    def getInstance(name, arg1, arg2):
       subclass = globals()[name]
       return subclass(arg1, arg2)
from base import Base

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

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

我不知道是否理解您的意思,
如果需要子类,为什么要将它们从类中移除?然后让我们进入类中,在需要它们的地方,可以从类导入子类

据我所知,您有:

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

    例如:

    # 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(name,base,dict)
    返回一个新的类型对象。这本质上是class语句的一种动态形式。名称字符串是类名,并成为
    \uu name\uu
    属性;bases元组逐项列出基类,并成为
    \uuu bases\uuu
    属性;而
    dict
    字典是包含类主体定义的名称空间,并成为
    \uu dict\uu
    属性。例如,以下两条语句创建相同类型的对象:

    >>> class X(object):
    ...     a = 1
    ...
    >>> X = type('X', (object,), dict(a=1))
    
    为什么不将resolve移到manager类中?请查看中的域类。我不确定是否需要解决。。。您可以直接从
    self.\uuuuu class\uuuu.\uuuu name\uuuu
    获取类名,并使用python函数,如
    type()
    isinstance()
    检查它们是否是特定类型

    还可以查看:


    我有60多个子类。以前,当它们与我的基类位于同一个文件中时,该文件的位置超过800 LOC。这或多或少是不可能找到东西的。60子类!!它们是干什么用的?虽然这样做有效,但这对性能有什么影响?每次调用该方法时都要重新导入60个子类(这是以递归方式完成的)不是很昂贵吗?导入的模块缓存在
    sys.modules
    中,因此我不希望有任何重大影响。此外,我还必须对每个文件执行package.filename import*
    中的
    操作。将来,每次添加新文件时,我都必须记住添加更多导入。是否有更简洁的语法用于导入包的所有模块的所有成员?您可以执行“导入包”,然后将对象引用为package.filename.member1、package.filename2.member2等,因为我的子类实例创建者是自动的(基于字符串),我不知道子类在哪个文件中。这只是将导入错误传播到工厂类。由于factory类只从sub1导入*
    ,从sub2导入*…执行
    ,而每个子类从基本导入*
    执行
    ,因此在尝试导入sub2后将抛出ImportError。尝试捕获异常并传递它意味着将跳过所有其他导入。除非您将factory类放入它自己的文件中。另一种解决方案可能是更好地控制子类,并创建一个dict来指定字符串和派生类之间的映射,然后将60个基类中的每一个显式地导入工厂类。我这样做了-我的工厂类从每个子类(导入基类)导入所有内容。同时,我的基类(位于单独的文件中)导入factory类。这仍然会导致循环导入。基类不需要了解工厂类。也许您可以发布一些关于它们是如何交织在一起的代码?resolve()只是用于确定类类型并返回自身的新实例吗?它返回一个Base子类的实例。将resolve移到负责返回正确实例的factory类中如何?