python
February 7, 2023

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