Ключевые виды методов в классах Python
Рассмотрим типы методов, создаваемых в классе, их различия и особенности использования. В качестве демонстрационного примера рассмотрим следующий класс:
import json
class Animal():
obj_type = 'animal'
def __init__(self, name, length, weight):
self.name = name
self.length = length
self.weight = weight
def grow_weight(self, mult_weight):
start_weight = self.weight
self.weight = self.calc_weight_grow(self.weight, mult_weight)
print(f'grow of {self.__class__.obj_type} {self.name} \
from weight {start_weight} to {self.weight}')
@classmethod
def from_json(cls, fn):
print(f'creating new {cls.obj_type}')
with open('turkey.json', 'r') as f_r:
d = json.load(f_r)
return cls(d['name'], d['length'], d['weight'])
@staticmethod
def calc_weight_grow(weight, mult_weight):
return weight*mult_weight
def __str__(self):
return f"I\'m {self.name} with length - {self.length}, weight = {self.weight}"
В теле класса объявлены 3 типа методов - методы класса (декоратор @classmethod), статические методы (@staticmethod) и методы экземпляра (без декоратора). Первые имеют доступ к шаблону класса, его переменным (через первый аргумент), третьи к атрибутам класса и экземпляра (через первый аргумент), а вторые являются обособленными функциями, не имеющими доступ к состоянию класса и его объектов.
Для инициализации экземпляра класса в последующих примерах запишем json файл:
import json
d = {'name':'turkey', 'length':0.1, 'weight':1}
with open('turkey.json', 'w') as f_w:
json.dump(obj=d, fp=f_w)
del dТеперь рассмотрим особенности вызова перечисленных трех типов методов. На самом классе:
turkey1 = Animal.from_json('turkey.json')from_json как метод класса корректно срабатывает и имеет доступ к переменной класса.
Animal.calc_weight_grow(3,4)
Так же без проблем вызывается статический метод. А вот метод экземпляра использовать на классе не удастся:
Animal.grow_weight(3)
Теперь продемонстрируем, что все три метода успешно вызываются созданном выше на экземпляре класса (turkey1):
turkey2 = turkey1.from_json('turkey.json')
print(turkey2)
turkey2.calc_weight_grow(3,4)
turkey2.grow_weight(3)
print(turkey2)Последний метод экземпляра класса получается доступ ко всем переменным и класса и экземпляра.
Таким образом методы класса и статические методы можно вызывать на классе или на экземпляре. Методы экземпляра класса - только на созданном объекте. Методы класса имеют доступ к классу и с ними можно обойти ограничение Python на создание только одного конструктора (традиционным методом __init__). Статические методы полезны как независимые от внутреннего состояния класса или его экземпляра функции, которые тем самым становится проще отлаживать.