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__ 只接受一个参数,名字。因此,您可以将namesurname 传递给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__

转载--------Python中:self和__init__的含义 + 为何要有self和__init__

Python中的__init__和__new__

Python类中super()和__init__()的关系

深入理解Python中的 __new__ 和 __init__