У меня есть класс с двумя методами класса (использующими classmethod() функцию) для получения и установки того, что по сути является статической переменной. Я пытался использовать property() функцию с этими, но это приводит к ошибке. Я смог воспроизвести ошибку следующим образом в интерпретаторе:
classFoo(object): _var = 5 @classmethod defgetvar(cls): return cls._var @classmethod defsetvar(cls, value): cls._var = value var = property(getvar, setvar)
Я могу продемонстрировать методы класса, но они не работают как свойства:
>>> f = Foo() >>> f.getvar() 5 >>> f.setvar(4) >>> f.getvar() 4 >>> f.var Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'classmethod'objectisnotcallable >>> f.var=5 Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'classmethod'objectisnotcallable
Возможно ли использовать property() функцию с @classmethod оформленными функциями?
Переведено автоматически
Ответ 1
3.8 < Python < 3.11
Можно использовать оба декоратора вместе. Смотрите Этот ответ .
Python 2 и python 3 (работает и в 3.9-3.10)
Свойство создается в классе, но влияет на экземпляр. Итак, если вам нужно classmethod свойство, создайте свойство в метаклассе.
или, используя metaclass=... синтаксис Python 3 и метакласс, определенный вне foo тела класса, и метакласс, ответственный за установку начального значения _var:
Обновление: в @classmethodPython 3.13@property была удалена возможность связывания и 😕.
В Python 3.9 Вы могли бы использовать их вместе, но (как отмечено в комментарии @xgt) это было устаревшим в Python 3.11, поэтому оно больше не поддерживается (но оно может работать некоторое время или быть повторно введено в какой-то момент).
Метод get [свойства] не будет вызываться, когда к свойству обращаются как к атрибуту класса (C.x), а не как к атрибуту экземпляра (C().x). Если вы хотите переопределить операцию __get__ для свойств при использовании в качестве атрибута класса, вы можете создать подкласс property - это сам тип нового стиля - для расширения его метода __get__ , или вы можете определить тип дескриптора с нуля, создав класс нового стиля, который определяет методы __get__, __set__ и __delete__ .
ПРИМЕЧАНИЕ: Приведенный ниже метод на самом деле не работает для установщиков, только для получателей.
Поэтому я считаю, что предписанным решением является создание ClassProperty в качестве подкласса property .