Python:从基础 class 创建自身的新实例(可能通过反射?)
Python: Creating a new instance of itself from a base class (possibly via reflection?)
我的代码如下所示,我正在尝试重构它。
# 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()
由于问题需要递归解决,classes会通过func()
递归调用自己(所以A会做一些A,再做一些A,直到递归函数结束) ,对我来说重构它的最佳方法是动态创建 class。如果有办法获得最终的运行时间 class,我可以将其重构为:
# 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__()
我认为您在这里真正想要的是使用 class 方法而不是常规方法。
您似乎没有在任何地方使用 self
。事实上,您甚至不需要一个 exist 的实例来让这些函数工作。所以:
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
我的代码如下所示,我正在尝试重构它。
# 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()
由于问题需要递归解决,classes会通过func()
递归调用自己(所以A会做一些A,再做一些A,直到递归函数结束) ,对我来说重构它的最佳方法是动态创建 class。如果有办法获得最终的运行时间 class,我可以将其重构为:
# 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__()
我认为您在这里真正想要的是使用 class 方法而不是常规方法。
您似乎没有在任何地方使用 self
。事实上,您甚至不需要一个 exist 的实例来让这些函数工作。所以:
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