Использование свойства () для методов класса - PullRequest
148 голосов
/ 24 сентября 2008

У меня есть класс с двумя методами класса (использующими функцию classmethod ()) для получения и установки того, что по сути является статической переменной. Я пытался использовать функцию property () с ними, но это приводит к ошибке. Мне удалось воспроизвести ошибку со следующим в интерпретаторе:

class Foo(object):
    _var = 5
    @classmethod
    def getvar(cls):
        return cls._var
    @classmethod
    def setvar(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' object is not callable
>>> f.var=5
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: 'classmethod' object is not callable

Можно ли использовать функцию property () для функций, декорированных методом класса?

Ответы [ 13 ]

1 голос
/ 25 сентября 2008

Попробуйте, она выполнит свою работу без изменения / добавления большого количества существующего кода.

>>> class foo(object):
...     _var = 5
...     def getvar(cls):
...         return cls._var
...     getvar = classmethod(getvar)
...     def setvar(cls, value):
...         cls._var = value
...     setvar = classmethod(setvar)
...     var = property(lambda self: self.getvar(), lambda self, val: self.setvar(val))
...
>>> f = foo()
>>> f.var
5
>>> f.var = 3
>>> f.var
3

Функция property нуждается в двух callable аргументах. дайте им лямбда-обертки (которые он передает экземпляру в качестве первого аргумента) и все хорошо.

0 голосов
/ 18 октября 2017

После поиска в разных местах я нашел метод для определения свойства класса действует с Python 2 и 3.

from future.utils import with_metaclass

class BuilderMetaClass(type):
    @property
    def load_namespaces(self):
        return (self.__sourcepath__)

class BuilderMixin(with_metaclass(BuilderMetaClass, object)):
    __sourcepath__ = 'sp'        

print(BuilderMixin.load_namespaces)

Надеюсь, это кому-нибудь поможет:)

0 голосов
/ 24 сентября 2008

Вот мое предложение. Не используйте методы класса.

Серьезно.

В чем причина использования методов класса в этом случае? Почему бы не иметь обычный предмет обычного класса?


Если вы просто хотите изменить значение, свойство не очень полезно, не так ли? Просто установите значение атрибута и покончите с этим.

Свойство следует использовать только в том случае, если есть что скрывать - что может измениться в будущей реализации.

Может быть, ваш пример урезан, и у вас закончились какие-то адские вычисления. Но это не похоже, что свойство добавляет значительную ценность.

Методы "конфиденциальности" под влиянием Java (в Python имена атрибутов, начинающиеся с _) не очень полезны. Рядовой от кого? Точка приватности немного туманна, когда у вас есть источник (как у вас в Python.)

Под влиянием Java используются методы получения и установки EJB-стиля (часто выполняемые как свойства в Python), чтобы упростить примитивный самоанализ Java, а также пройти проверку с помощью компилятора статического языка. Все эти методы получения и установки не так полезны в Python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...