7

Python supports a @property decorator for instances like so:

class MyClass(object):
    def __init__(self):
        self._friend_stack = [1]
    @property
    def current_friend(self):
        return self._friend_stack[0]

myobj = MyClass()
myobj.current_friend # 1

Is it possible to have something like this for classes, so that the behavior is something like this (along with setter and getter methods, for instance):

class MyClass(object):
    _friend_stack = [1]

    @property
    def current_friend(cls):
        return cls._friend_stack[0]

MyClass.current_friend # 1
Pablo
  • 10,425
  • 1
  • 44
  • 67
  • 2
    Think you want `@classmethod` – OneCricketeer Nov 15 '16 at 23:00
  • 1
    Possible duplicate of [Static class variables in Python](http://stackoverflow.com/questions/68645/static-class-variables-in-python) – OneCricketeer Nov 15 '16 at 23:01
  • `@classmethod` would allow me to do `MyClass.current_friend()`, but it would not let me do `MyClass.current_friend = 2`. I'd like the latter behavior. I'd also like to have the chance to run code when accessing the variables. – Pablo Nov 15 '16 at 23:05
  • Could you show a fictitious use case where a class-property has a use? Most properties rely on `self` to do something behind the scenes. –  Nov 16 '16 at 00:10

1 Answers1

8

In Python 3:

class MyMeta(type):
    def current_friend(cls):
        return cls._friend_stack[0]
    current_friend = property(current_friend)

class MyClass(metaclass=MyMeta):
    _friend_stack = [1]

[mad laugh follows]

Stephane Martin
  • 1,612
  • 1
  • 17
  • 25
  • 3
    This (using a metaclass) is actually the proper and [seemingly only way to do it](https://mail.python.org/pipermail/python-ideas/2011-January/008959.html) as of version 3.5. There's an [open issue](https://bugs.python.org/issue24941) regarding adding a `classproperty` decorator, and Erik Bray suggests that writing a pure Python version is "trivial". However, [his implementation](https://mail.python.org/pipermail/python-ideas/2015-August/035349.html) is somewhat broken: as Nick Coghlan pointed out, setting/deleting the attribute through the class will bypass the descriptor entirely. –  Nov 16 '16 at 02:19
  • Is there anything in documentation that refers to this please ? Need to read more. – Ebram Shehata May 24 '21 at 14:48