Страницы

Поиск по вопросам

пятница, 20 декабря 2019 г.

Как сделать статическое свойство класса в питоне?

#python #ооп


Пробую так:

class ChatCodes:

   _chat = 'cht'

   @property
   def chat(self):
      return self._chat


если использую так:

print(ChatCodes.chat + 'any_str')


то появляется ошибка:


  unsupported operand type(s) for +: 'property' and 'str'


как правильно создать статическое свойство?
    


Ответы

Ответ 1



В принципе, объявленный параметр класса со значением - уже может использоваться как статическое свойство >>> class MyClass: ... param = "value" ... >>> MyClass.param 'value' >>> Это же значение будет доступно и для экземпляра класса. Разве что у экземпляра есть опасность, что значение свойства изменится в процессе работы. Тут стоит позаботиться, чтоб этот параметр не изменялся и/или чтоб обращение к свойству шло исключительно через имя класса, а не экземпляра. Можно использовать статический метод - объявляется с помощью аннотации @staticmethod. Правда и обращаться к нему придётся как к методу, а не свойству >>> class MyClass: ... @staticmethod ... def param(): ... return "value" ... >>> MyClass.param >>> MyClass.param() 'value' >>> Если достаточно ленивой инициализации (то есть обращаться к свойству будем через экземпляр класса), то можно использовать аннотацию @property >>> class MyClass: ... @property ... def param(self): ... return "value" ... >>> MyClass.param >>> MyClass.param() Traceback (most recent call last): File "", line 1, in TypeError: 'property' object is not callable >>> >>> m = MyClass() >>> m.param 'value' Ну и вариант на любителя (на случай, когда значение свойства нужно вычислить): >>> class MyClass: ... def _method_to_create_static_prop(): ... return "value" ... param = _method_to_create_static_prop() ... del _method_to_create_static_prop ... >>> MyClass.param 'value' >>> MyClass._method_to_create_static_prop Traceback (most recent call last): File "", line 1, in AttributeError: class MyClass has no attribute '_method_to_create_static_prop' >>>

Ответ 2



Если вы хотите, чтобы C.class_property вызывало бы метод класса, можно метакласс __getattr__ метод определить: #!/usr/bin/env python3 import random class ClassPropertyMeta(type): def __getattr__(cls, key): if key == 'class_property': return cls._get_class_property() raise AttributeError(f"<{cls!r}.{key!r}>") class C(metaclass=ClassPropertyMeta): @classmethod def _get_class_property(cls): return random.random() print(C.class_property) # -> 0.333495437410268 Аналогично для модулей в Питоне 3.7 (PEP 562): #!/usr/bin/env python3 import random def __getattr__(name): print(name) return random.random() if __name__ == '__main__': import module_attr print(module_attr.module_property) # -> module_property # -> 0.420563286888762

Комментариев нет:

Отправить комментарий