(I know that there are similar questions already answered, but my question focuses more on the reason behind the solution instead of the solution itself).
I have been in need of something like a "class property" in Python, and I have searched through existing questions. Some answers provide a workaround, but I cannot understand why python disabled chaining @classmethod
and @property
. Is there any explanation for this?
Also, I've found that all the currently available solutions have limitations, which are listed below. The posts I have read include:
- An answer which points out that chaining
@classmethod
and@property
has been disabled since Python 3.13 - Another solution which defines a customized
classproperty
descriptor. But this workaround fails to prevent modification. For example, the following code derived from the original answer will not raise an exception when modification overx
is attempted.class classproperty(property): def __get__(self, owner_self, owner_cls): return self.fget(owner_cls) def __set__(self, instance, value): raise AttributeError("can't set attribute") class C(object): @classproperty def x(cls): return 1 print(C.x) C.x = 2 print(C.x) # Output: 2 # no exception raised # cannot prevent modification
- A solution by writing the class property into metaclass. This method successfully prevents attempted modifications, but with this method, access to class variables will only be possible via class, not via instance.
class CMeta(type): @property def x(cls): return 1 class C(object, metaclass=CMeta): ... print(C.x) # C.x = 2 # AttributeError: property 'x' of 'CMeta' object has no setter # print(C().x) # AttributeError: 'C' object has no attribute 'x'
So is there an ultimate way to resolve all the above mentioned problems and allow for a class property implementation satisfying the following two conditions?
- Can prevent attempted modifications
- Can be accessed from both class and instance