J. C. Leitão J. C. Leitão - 1 month ago 8
Python Question

Idiom to define a class property

To define a property, we can use

class MyClass(object):

def __init__(f):
self._f = f

def custom_function(self):
self._f += 1

@property
def f(self):
return self._f


such that

>>x = MyClass(1)
>>print(x.f) # prints 2





Is there any standard way to define the interface

>>MyClass.f # <- calls custom classmethod


? I.e. a "
@classproperty
".

I'm aware of
@classmethod
but I don't want the interface to have the call
()
.

Answer Source

You have two options: Put a property on the metaclass, or create a custom descriptor to translate a .__get__ directly into a function call, regardless of the context; the property descriptor only does this when there is an instance, returning self for when accessed on the class.

Metaclass:

class MetaClass(type):
    @property
    def f(cls):
        return cls._f

class MyClass(object):
    __metaclass__ = MetaClass

    def __init__(f):
        self._f = f

Custom descriptor:

class classproperty(object):
    def __init__(self, getter):
        self.getter = getter

    def __get__(self, instance, cls):
        return self.getter(cls)

class MyClass(object):
    def __init__(f):
        self._f = f

    @classproperty
    def f(cls):
        return cls._f

Be aware that there are limitations to the latter approach.