Ключевые виды методов в классах 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__). Статические методы полезны как независимые от внутреннего состояния класса или его экземпляра функции, которые тем самым становится проще отлаживать.