0

我想定义一个类 AorB,这样所有 A 都是 AorB,所有 B 都是 AorB,而这些都是 AorB。当然,A 和 B 应该是 AorB 的子类。问题在于AorB.__init__,当我无法说服自己时,它应该是别的东西。我可以定义一个 AorB 工厂,但如果可能的话,我宁愿拥有 AorB 构造函数。

class AorB:
    def __init__(self,par):
        if par: self=A(par) #!
        else: self=B()      #!
    @staticmethod
    def from_par(par):
        if par: return A(par)
        else: return B()
class A(AorB):
    def __init__(self,par):
        self.par=par
class B(AorB):
    def __init__(self):
        pass
print(
    AorB.from_par(5),
    AorB.from_par(0),
    AorB(5),
    AorB(0),
    sep="\n")

我知道分配给 self 在这里不起作用,但我只是想表明意图。正如我所说, factory (from_par) 工作正常,我只想将其称为AorB,而不是AorB.from_par

PS。我知道,__init__可能为时已晚,自我的类型已经确定。随意在您的答案中使用元类。是时候让我了解一些关于它们的有用信息了。:-)

4

1 回答 1

3

你不能,不能__init__。一旦__init__被调用,实例就已经被创建

你想要一个工厂函数

class AorB: pass

class A(AorB):
    def __init__(self,par):
        self.par=par

class B(AorB):
    def __init__(self):
        pass

def AorB(par):
    return A(par) if par else B()

从 API 的角度来看,没有区别AorB是产生一个A()或一个B()实例的可调用对象。

另一种可能的方法是定义一个__new__函数。这是类构造函数:

class AorB:
    def __new__(cls, par=None):
        if cls is not AorB: return super().__new__(cls)
        return super().__new__(A) if par else super().__new__(B)

class A(AorB):
    def __init__(self, par):
        self.par = par

class B(AorB):
    def __init__(self, par=None):
        pass

这只是一个更复杂的工厂功能,真的。请注意,该__new__方法返回super().__new__基于 的子类之一的结果par,因此无论它们是否想要一个参数,AB将传递一个参数。par

if cls is not AorB行需要允许实例化A()B()直接;如果这不是必需的并且仅使用AorB工厂类,则可以省略该行。

于 2013-06-24T23:41:07.500 回答