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