Python:从基类创建自身的新实例(可能通过反射?)



我有如下代码,我正在尝试重构它。

# Abstract, do not instantiate Base
class Base:
    ...

class A(Base):
    ...
    def func():
        x = A(1, 2, 3)
        x.x()
        y = A(4, 5, 6)
        y.y()
        z = A(7, 8, 9)
        z.z()
class B(Base):
    ...
    def func():
        x = B(1, 2, 3)
        x.x()
        y = B(4, 5, 6)
        y.y()
        z = B(7, 8, 9)
        z.z()

class C(Base):
    ...
    def func():
        x = C(1, 2, 3)
        x.x()
        y = C(4, 5, 6)
        y.y()
        z = C(7, 8, 9)
        z.z()

由于需要递归解决的问题,类将通过func()递归地调用自己(因此A将生成一些A,这些A将生成更多A,直到递归函数完成),对我来说重构它的最佳方法是动态创建类。如果有一种方法可以获得最终的运行时类,我可以将其重构为:

# Abstract, do not instantiate Base
class Base:
    ...
    def func():
        constructor = # Magic here to get the actual class type's constructor
        # I'm guessing reflection would do something like this...? I don't know.
        x = constructor.__init__(1, 2, 3) # If this is an A, make an A... if it's a B, make a B... etc
        x.x()
        y = constructor.__init__(4, 5, 6)
        y.y()
        z = constructor.__init__(7, 8, 9)
        z.z()
class A(Base):
    ...

class B(Base):
    ...

class C(Base):
    ...

我不太了解Python和它的反射能力,或者是否有其他更好的方法来做到这一点。

这能做到吗?

有比反思更好的方法吗?

注意:构造函数参数只是我任意设置的占位符。

注2:性能与此无关,我只是对这是否可能感兴趣,如果可能——如何?


编辑:基于回答的解决方案,此代码工作:

class Test:
    def __init__(self):
        print("Made BaseClass")
    def func(self):
        rofl = self.__class__()
        print(rofl.__class__)
class SubClass(Test):
    def __init__(self):
        super().__init__()
        print("Made SubClass")
a = SubClass()
a.func()

您可以使用值的__class__属性:

class A(object):
     pass
class B(A):
     pass
b = B()
c = b.__class__()

我认为这里你真正想要的是使用类方法而不是常规方法。

你似乎没有在任何地方使用self。事实上,您甚至不需要一个实例存在来让这些函数工作。所以:

class Test:
    def __init__(self):
        print("Made BaseClass")
    @classmethod
    def func(cls):
        rofl = cls()
        print(rofl.__class__)
class SubClass(Test):
    def __init__(self):
        super().__init__()
        print("Made SubClass")

或者,对于您的实际情况:

class Base:
    def __init__(self, *args): pass
    def x(self): pass
    def y(self): pass
    def z(self): pass
    @classmethod
    def func(cls):
        x = cls(1, 2, 3)
        x.x()
        y = cls(4, 5, 6)
        y.y()
        z = cls(7, 8, 9)
        z.z()
class A(Base): pass
class B(Base): pass
class C(Base): pass
a = A()
a.func() # calls Base.func, constructs and uses A instances
A.func() # also calls Base.func, constructs and uses A instances

相关内容

  • 没有找到相关文章

最新更新