Python __init__ 和 classmethod,它们是不是必须具有相同数量的参数?
Posted
技术标签:
【中文标题】Python __init__ 和 classmethod,它们是不是必须具有相同数量的参数?【英文标题】:Python __init__ and classmethod, do they have to have the same number of args?Python __init__ 和 classmethod,它们是否必须具有相同数量的参数? 【发布时间】:2018-08-28 11:22:10 【问题描述】:所以类方法可以用作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 。我错过了什么吗?
【问题讨论】:
cls(name,surname)
通话 __init__
.
谢谢,现在明白了。
不,它们不必有相同数量的参数,你可以让alternative_init()
做它的代码所说的任何事情。但是Myclass.alternative_init("alex","james")
应该给出什么?一个包含名称列表的实例?两个实例? (从生成器产生?作为列表?)还是什么?
【参考方案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
【讨论】:
好的,所以基本上我可以在类方法中创建一个实例,然后向该实例添加属性。谢谢你的解释。 就是这样,你可以。但是对于这种特殊情况,最好在__init__
中使用默认参数surname
,因为如果您调用__init__
,您的实例的surname
属性将未定义【参考方案2】:
__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
【讨论】:
据我了解,由于您返回 v,因此您的alternative_init
方法更像是 alternative_new
【参考方案3】:
因为Myclass.alternative_init("alex","james")
调用与MyClass(name,surname)
相同的cls(name, surname) 也与__init__(self,name,surname)
相同,但您的__init__
函数没有surname
参数。您可以通过__init__(self,name,surname=None)
将surname
设为可选
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)
【讨论】:
【参考方案4】:在 Python 中,传递给方法的第一个参数始终是对象本身。 如果您现在使用名称调用您的方法,您将获得 self 作为第一个参数,并将名称作为第二个参数。
当您现在从类方法内部调用 init 方法时,python 不知道应该如何处理姓氏。
【讨论】:
【参考方案5】: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")
【讨论】:
您好!虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。以上是关于Python __init__ 和 classmethod,它们是不是必须具有相同数量的参数?的主要内容,如果未能解决你的问题,请参考以下文章
Python(和 Python C API):__new__ 与 __init__
Python中:self和__init__的含义 + 为何要有self和__init__