我正在努力了解如何使这项工作。我想使用类方法实例化父类。这段代码给了我一个错误:
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个参数Child
,self
,a
,b
初始化c
类。但是Child
类需要5个参数。
我如何实现此功能?我知道除非绝对必要,否则我们不应该使用工厂方法。假设这是必要的。
答案 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__
。并且,您需要能够使用原始签名完全构造类以使用原始类方法,因此您也需要在子类中覆盖类方法。