Issue44973
Created on 2021-08-22 06:39 by tusharsadhwani, last changed 2022-04-11 14:59 by admin. This issue is now closed.
| Messages (2) | |||
|---|---|---|---|
| msg400051 - (view) | Author: Tushar Sadhwani (tusharsadhwani) * | Date: 2021-08-22 06:39 | |
Starting with Python3.9, `@classmethod` can be stacked on top of `@property`, but it seems that `@staticmethod` cannot.
>>> class C:
... @classmethod
... @property
... def cm(cls):
... return cls.__name__
... @staticmethod
... @property
... def magic_number():
... return 42
...
>>> C.cm
'C'
>>> C.magic_number
<property object at 0x7f0ad3c1ea90>
>>>
This feels like inconsistent behaviour, plus, having staticmethod properties can be useful for creating read-only class attributes, for eg:
class C:
@staticmethod
@property
def FINE_STRUCTURE_CONSTANT():
return 1 / 137
This would make it hard to accidentally modify the constant inside the class.
|
|||
| msg400081 - (view) | Author: Raymond Hettinger (rhettinger) * ![]() |
Date: 2021-08-22 17:25 | |
The classmethod and staticmethod decorators have somewhat different semantics. Accessing a classmethod with C.cm creates a bound method object which has both __call__ and __get__. In contrast, accessing a staticmethod with C.sm returns the underlying function. So there is no opportunity for a customized __get__ method as we have with classmethod. Also, even if C.sm did return a custom descriptor, the code example still can't be made to work because the __get__ method on property objects is hardwired to pass in an instance.¹ That means that the underlying method must have a "self" argument. Another issue is that properties have __set__ and __delete__ methods which could not be made to work without a reference to the class or instance. To make a read-only class variable, a metaclass would be needed. While it is possible to write a descriptor to make C.FINE_STRUCTURE_CONSTANT call a function that returns 1/137, there is no way for the descriptors to block the assignment: C.FINE_STRUCTURE_CONSTANT = 1 / 100 Thanks for the suggestion, but I don't think this can be made to work. ¹ https://docs.python.org/3/howto/descriptor.html#properties |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:59:49 | admin | set | github: 89136 |
| 2021-08-22 17:38:02 | rhettinger | set | assignee: rhettinger |
| 2021-08-22 17:25:36 | rhettinger | set | status: open -> closed nosy:
+ rhettinger resolution: rejected |
| 2021-08-22 06:39:43 | tusharsadhwani | create | |
