我遇到一种情况,我正在使用@classmethod
为类创建构造函数。在此构造函数中,将调用一个函数,然后依次调用另一个函数。但这要么不起作用,要么(可能是)我正在做一些使其不起作用的事情。这是一个缩影示例:
class testclass:
def __init__(self, x):
self.x = x
@classmethod
def constructor(cls, x):
adj_x = cls.outer_adjust(cls, x)
return testclass(adj_x)
def outer_adjust(self, x):
return self.inner_adjust(x)
def inner_adjust(self, x):
return x + 1
test_instance = testclass.constructor(4)
这会产生一条错误消息:
inner_adjust() missing 1 required positional argument: 'x'
我可以通过将自身显式传递给inner_adjust
来使其正常工作,例如
def outer_adjust(self, x):
return self.inner_adjust(self, x)
但这意味着outer_adjust
之外不能使用constructor
方法,这不是我想要的。
非常感谢收到任何帮助。
这是一个更详细的示例,其中显示了两个构造函数。我正在尝试遵循中描述的构造方法 What is a clean, pythonic way to have multiple constructors in Python? 从本质上讲,这是构造函数进行一些处理,以确定在实例化类时应将哪些变量传递给 init 。 两个构造函数都给出相同的错误:
if_char_is_z_make_it_a() missing 1 required positional argument: 'char_input'
和以前一样,我需要能够在构造函数之外(即,正常使用类时)使用if_char_is_make_it_a函数。
class testclass:
def __init__(self, char):
self.char = char
@classmethod
def constructor_from_int(cls, int_input):
as_char = chr(int_input)
char = cls.process_char(cls, as_char)
return testclass(char)
@classmethod
def constructor_from_char(cls, char_input):
char = cls.process_char(cls, char_input)
return testclass(char)
def process_char(self, char_input):
processed_char = '(' + char_input + ')'
output_char = self.if_char_is_z_make_it_a(processed_char)
return output_char
def if_char_is_z_make_it_a(self, char_input):
if char_input == '(z)':
return '(a)'
return char_input
test_instance = testclass.constructor_from_char('a')
答案 0 :(得分:2)
从cls.outer_adjust
调用constructor
时,您正在调用未绑定的outer_adjust
方法。
因此,您将类本身作为self
而不是实例传递给希望接收实例作为参数的方法。
尽管,没有真正理由使用constructor
方法。这正是__init__
的目的。
class testclass:
def __init__(self, x):
self.x = self.outer_adjust(x)
def outer_adjust(self, x):
return self.inner_adjust(x)
def inner_adjust(self, x):
return x + 1
test_instance = testclass(4)
如果您确实需要在实例化之前 上完成x
上的转换,请改用__new__
。虽然,这通常不是必需的。
如果由于某种原因您仍然需要一个constructor
方法,例如,如果您想要多个构造函数。然后请记住outer_adjust
和inner_adjust
是实例方法,这意味着在创建实例之后,必须将它们称为。
class testclass:
def __init__(self, x):
self.x = x
@classmethod
def constructor1(cls, x):
instance = cls(x)
instance.outer_adjust()
return instance
@classmethod
def constructor2(cls, x):
instance = cls(x)
instance.inner_adjust()
return instance
def outer_adjust(self):
print('Do something else')
return self.inner_adjust()
def inner_adjust(self):
self.x += 1
请注意,我不需要在构造函数方法中调用testclass
,而只需调用cls
。由于这是一个类方法,因此我们无需显式命名该类。这样会更好,特别是如果您要使用继承。
答案 1 :(得分:1)
基本上,您在这里所做的工作应通过用作构造函数的__new__完成。
class testclass:
def __init__(self, x):
self.x = x
def __new__(cls, *args, **kwargs):
instance = super(testclass, cls).__new__(cls, *args, **kwargs)
instance.outer_adjust(args[0])
return instance
def outer_adjust(self, x):
return self.inner_adjust(x)
def inner_adjust(self, x):
self.x = x + 1
test_instance = testclass(4)
答案 2 :(得分:0)
您正在滥用self
。类方法的重点是使用cls
参数作为构造函数,而不是用testclass(adj_x)
显式命名该类。另外,在cls.outer_adjust(cls, x)
调用期间,您正在传递类而不是实例,因为您没有使用任何实例属性,所以会发生。
关于您的问题,无法避免使用x
参数。 inner_adjust
通过1
增加一些值,因此您必须给它一些增加的值。这个想法是要
def constructor(cls, x):
return cls(x)
def inner_adjust(self):
return self.x += 1
然后做类似的事情
object= testclass.constructor(12)
object.inner_adjust()