Python etc / types.DynamicClassAttribute

types.DynamicClassAttribute

types.DynamicClassAttribute is a decorator that allows having a @property that behaves differently when it's called from the class and when from the instance.

from types import DynamicClassAttribute

class Meta(type):
    @property
    def hello(cls):
        return f'hello from Meta ({cls})'

class C(metaclass=Meta):
    @DynamicClassAttribute
    def hello(self):
        return f'hello from C ({self})'

C.hello
# "hello from Meta (<class '__main__.C'>)"

C().hello
# 'hello from C (<__main__.C object ...)'

Practically, it is used only in enum to provide name and value properties for instances while still allowing to have name and value class members:

import enum

class E(enum.Enum):
    value = 1

E.value
# <E.value: 1>

E.value.value
# 1