Python __init__和classmethod,他们必须具有相同数量的args吗?

时间:2018-03-19 19:19:53

标签: python oop constructor arguments class-method

因此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。我错过了什么吗?

5 个答案:

答案 0 :(得分:3)

__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 中创建一个类实例,并添加一个额外的参数:

-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")