Python __init__ и classmethod

Таким образом, методы класса могут использоваться в качестве альтернативного "конструктора" в 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 . Я что-то пропустил?

4 ответа

__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

Вы можете сделать то, что вы хотите, как это:

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

Так как 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)

В Python первым аргументом, переданным методу, всегда является сам объект. Если вы сейчас вызовете свой метод с именем, вы получите self в качестве первого параметра, а имя - в качестве второго.

Когда вы вызываете метод init изнутри вашего метода класса, python не имеет ни малейшего представления, что он должен делать с фамилией.

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

Другие вопросы по тегам