Ответ 1
Методы экземпляра
При создании метода экземпляра первый параметр всегда self
.
Вы можете называть его всем, что хотите, но значение всегда будет одинаковым, и вы должны использовать self
, поскольку это соглашение об именах.
self
(обычно) передается скрытно при вызове метода экземпляра; он представляет экземпляр, вызывающий метод.
Вот пример класса с именем Inst
, который имеет метод экземпляра под названием introduce()
:
class Inst:
def __init__(self, name):
self.name = name
def introduce(self):
print("Hello, I am %s, and my name is " %(self, self.name))
Теперь, чтобы вызвать этот метод, нам сначала нужно создать экземпляр нашего класса.
Как только у нас есть экземпляр, мы можем вызвать introduce()
на нем, и экземпляр будет автоматически передан как self
:
myinst = Inst("Test Instance")
otherinst = Inst("An other instance")
myinst.introduce()
# outputs: Hello, I am <Inst object at x>, and my name is Test Instance
otherinst.introduce()
# outputs: Hello, I am <Inst object at y>, and my name is An other instance
Как вы видите, мы не передаем параметр self
, он скрытно передается с оператором периода; мы вызываем метод экземпляра класса Inst
introduce
с параметром myinst
или otherinst
.
Это означает, что мы можем вызвать Inst.introduce(myinst)
и получить тот же результат.
Методы класса
Идея метода класса очень похожа на метод экземпляра, только разница заключается в том, что вместо того, чтобы передавать экземпляр скрытно в качестве первого параметра, мы теперь передаем сам класс в качестве первого параметра.
class Cls:
@classmethod
def introduce(cls):
print("Hello, I am %s!" %cls)
Поскольку мы передаем только класс методу, экземпляр не задействован. Это означает, что нам вообще не нужен экземпляр, мы вызываем метод класса, как если бы он был статической функцией:
Cls.introduce() # same as Cls.introduce(Cls)
# outputs: Hello, I am <class 'Cls'>
Обратите внимание, что снова Cls
передается скрытно, поэтому мы могли бы также сказать Cls.introduce(Inst)
и получить вывод "Hello, I am <class 'Inst'>
.
Это особенно полезно, когда мы наследуем класс из Cls
:
class SubCls(Cls):
pass
SubCls.introduce()
# outputs: Hello, I am <class 'SubCls'>