Created
February 16, 2026 10:51
-
-
Save sunmeat/3a458084b67226f480cd21cecc6a26bb to your computer and use it in GitHub Desktop.
інкапсуляція атрибуту класу, спосіб з геттером (не властивість!)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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