Есть ли способ создать свойство класса в Python? - PullRequest
8 голосов
/ 31 января 2010

По какой-то причине следующее не работает:

>>> class foo(object):
...     @property
...     @classmethod
...     def bar(cls):
...             return "asdf"
... 
>>> foo.bar
<property object at 0x1da8d0>
>>> foo.bar + '\n'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'property' and 'str'

Есть ли способ сделать это, или моя единственная альтернатива - прибегнуть к какой-то хитрости метакласса?

1 Ответ

6 голосов
/ 01 февраля 2010

Если вы хотите, чтобы дескриптор property срабатывал при получении атрибута от объекта X, тогда вы должны поместить дескриптор в type(X). Поэтому, если X является классом, дескриптор должен идти в типе класса, также известном как метакласс класса - никаких «хитростей» в этом нет, это просто вопрос совершенно общих правил.

В качестве альтернативы, вы можете написать свой собственный специализированный дескриптор. См. здесь для превосходного соглашения о дескрипторах с практическими рекомендациями. Редактировать например:

class classprop(object):
  def __init__(self, f):
    self.f = classmethod(f)
  def __get__(self, *a):
    return self.f.__get__(*a)()

class buh(object):
  @classprop
  def bah(cls): return 23

print buh.bah

испускает 23, по желанию.

...