在python中使用super with class方法

时间:2014-06-16 07:15:47

标签: python-2.7 inheritance super

我正在努力了解如何使这项工作。我想使用类方法实例化父类。这段代码给了我一个错误:

class Base(object):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    @classmethod
    def class_method(cls, a, b, c):
        return cls(a, b, c)

class Child(Base):
    def __init__(self, x, y, z, p):
        super(Child, self).class_method(x, y, z)
        self.p = p

c = Child(1, 2, 3, 10)

我收到以下错误:

TypeError: __init__() takes at least 5 arguments (4 given)

我也知道原因。这是因为cls变量包含Child类。因此,当调用cls(a, b, c)时,python会尝试使用4个参数Childselfab初始化c类。但是Child类需要5个参数。 我如何实现此功能?我知道除非绝对必要,否则我们不应该使用工厂方法。假设这是必要的。

2 个答案:

答案 0 :(得分:0)

在此特定实例中,您实际上不应使用@classmethod
@staticmethod是更好的解决方案

您注意到,类Child被传递到Base.do方法中。
但是如果您想始终使用类Base,只需像这样制作静态方法

class Base:
    @staticmethod
    def do(a, b, c):
        return Base(a, b, c)

使用@staticmethod更好,因为在类Base的{​​{1}}方法中,您希望始终使用同一类而不是其他类

比如说重命名类,这可能是一个小问题,但是可以使用IDLE(或几乎任何其他文本编辑器)的替换功能(Edit> Replce(Ctrl + H))来解决

答案 1 :(得分:0)

在这个确切的示例中,您应该做的是:

class Base(object):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    @classmethod
    def class_method(cls, a, b, c):
        return cls(a, b, c)

class Child(Base):
    def __init__(self, x, y, z, p):
        super().__init__(x, y, z)
        self.p = p

c = Child(1, 2, 3, 10)

但是,假设您确实想调用类方法,则永远不要在__init__中调用类方法(至少一个行为像工厂的方法)。初始化发生在实例化后 。因此,您需要覆盖__new__。并且,您需要能够使用原始签名完全构造类以使用原始类方法,因此您也需要在子类中覆盖类方法。