Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Created February 16, 2026 10:51
Show Gist options
  • Select an option

  • Save sunmeat/3a458084b67226f480cd21cecc6a26bb to your computer and use it in GitHub Desktop.

Select an option

Save sunmeat/3a458084b67226f480cd21cecc6a26bb to your computer and use it in GitHub Desktop.
інкапсуляція атрибуту класу, спосіб з геттером (не властивість!)
class Monster:
_count = 0 # атрибут класу позначено як умовно протектед
def __init__(self, health=100, attack=10, mana=50):
self.health = health
self.attack = attack
self.mana = mana
Monster._count += 1
print(f"створено монстра #{Monster._count}", end="")
if health != 100 or attack != 10 or mana != 50:
print(f" з параметрами h={health}, a={attack}, m={mana}")
else:
print()
@classmethod
def count(cls):
return cls._count
# починаючи з Python 3.11 офіційно заборонено обгортати @property декоратором @classmethod
# (і навпаки). з Python 3.13 ця можливість повністю видалена — код, який раніше працював,
# тепер видає помилку або повертає неправильний об'єкт. афіційне повідомлення в документації:
# Deprecated since version 3.11, removed in version 3.13: https://docs.python.org/uk/3/library/functions.html#classmethod
# Class methods can no longer wrap other descriptors such as property().
# причини:
# 1) @property жорстко прив'язаний до екземпляра
# метод __get__ у property завжди очікує, що йому передадуть instance (self)
# і що функція, яку він викликає, приймає self як перший аргумент.
# але коли додається @classmethod, перший аргумент стає cls, а не self, і це конфлікт.
#
# 2) неправильна поведінка при інспекції (abc, typing, mypy, IDE)
# багато інструментів (модуль abc, type checkers, IDE) перевіряють, чи є атрибут
# екземпляром property — через це вони викликають isinstance(attr, property).
# при комбінації @classmethod + @property (або навпаки) результат вже не є об'єктом property,
# і тому інструменти ламаються.
#
# 3) проблеми з успадкуванням та абстрактними класами
# коли є @abstractmethod + @classmethod + @property — механізм перевірки абстрактних методів
# часто випадково викликав дескриптор замість того, щоб просто подивитися на нього,
# тому виникають помилки або некоректна поведінка
@classmethod
def get_count(cls):
return cls._count
def print_info(self):
print(f"здоров'я = {self.health}, "
f"атака = {self.attack}, "
f"мана = {self.mana}")
if __name__ == "__main__":
monsters = []
monsters.append(Monster())
monsters.append(Monster(health=150))
monsters.append(Monster(200, 20, 100))
print("Monster._count ", Monster._count) # 3, небажаний варіант звернення
print("Monster.count() ", Monster.count()) # 3
print("Monster.get_count() ", Monster.get_count()) # 3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment