因此classmethods可以在python中用作替代“构造函数”,它们绑定到类而不是实例,到目前为止非常清楚。但我的问题是,如果必须在返回的类方法实例中使用与 init 中相同数量的参数。更确切地说:
class MyClass(object):
def __init__(self,name):
self.name=name
@classmethod
def alternative_init(cls,name,surname):
return cls(name,surname)
如果我尝试创建一个实例Myclass("alex")
工作正常,但如果我尝试创建一个实例Myclass.alternative_init("alex","james")
我有一个TypeError,因为我传递给许多参数,而init只有2。我错过了什么吗?
答案 0 :(得分:3)
__init__
只接受一个参数,即名称。因此,您可以将name
或surname
传递给cls
,但不能同时传递给classmethod
。但是,您可以在class MyClass(object):
def __init__(self,name):
self.name=name
def __setattr__(self, name, val):
self.__dict__[name] = val
@classmethod
def alternative_init(cls,name,surname):
v = cls(name)
v.surname = surname
return v
中创建一个类实例,并添加一个额外的参数:
-target 1.7 #Target version
-dontusemixedcaseclassnames #Specifies not to generate mixed-case class names while obfuscating
-dontskipnonpubliclibraryclasses #Specifies not to ignore non-public library classes
-dontpreverify #Specifies not to preverify the processed class files. when eventually targeting Android, it is not necessary, so you can then switch it off to reduce the processing time a bit.
-verbose #Specifies to write out some more information during processing
-optimizations !code/simplification/arithmetic,!code/allocation/variable
-keep class **
-keepclassmembers class *{*;}
-keepattributes *
答案 1 :(得分:2)
因为Myclass.alternative_init("alex","james")
调用的cls(名称,姓氏)与MyClass(name,surname)
相同,但与__init__(self,name,surname)
相同,但您的__init__
函数没有surname
参数。您可以surname
__init__(self,name,surname=None)
class MyClass(object):
def __init__(self,name,surname=None):
self.name=name
self.surname=surname
@classmethod
def alternative_init(cls,name,surname):
return cls(name,surname)
答案 2 :(得分:1)
你可以做你想做的事情:
class MyClass(object):
def __init__(self,name):
self.name=name
@classmethod
def alternative_init(cls,name,surname):
new_instance = cls(name)
new_instance.surname = surname
return new_instance
a = MyClass.alternative_init('Bob', 'Spongy')
print(a.name, a.surname)
# Bob Spongy
答案 3 :(得分:1)
在Python中,传递给方法的第一个参数始终是对象本身。 如果现在使用名称调用您的方法,您将获得self作为第一个参数,将名称作为第二个参数。
当您从classmethod内部调用 init 方法时,python不知道它应该用姓氏做什么。
答案 4 :(得分:0)
class MyClass(object):
def __init__(self,name):
self.name=name
@classmethod
def alternative_init(cls,name,surname):
return cls(name)
a = MyClass("alex")
MyClass.alternative_init("alex","james")