Is there a way to access the class name from a class variable?
Question:
I’m trying to set some default class variables in a base class so all subclasses are guaranteed to have a default value. Some of these I’d like to be dynamic based upon the subclass (DISPLAY_NAME
in the example below). The use of __qualname__
in _ExtensionBase
doesn’t work because it sets DISPLAY_NAME
to the static string "_ExtensionBase".
Is there a simpler way to do this, or any issues with the way I’ve found below? I haven’t stumbled into any, bit it feels like pushing some limits of the intended uses of property
and classmethod
class _ExtensionBase:
PRIORITY: float = 1.0
VERSION_STR: str = 'n/a'
@classmethod
@property
def DISPLAY_NAME(cls) -> str:
return cls.__name__
class ConcreteSubclass(_ExtensionBase): pass
assert ConcreteSubclass.DISPLAY_NAME == "ConcreteSubclass"
Answers:
Try this:
ConcreteSubclass.__name__
Per the note in Python 3.11’s entry on @classmethod
(link)
Changed in version 3.9: Class methods can now wrap other descriptors
such as property()
.
Changed in version 3.10: Class methods now inherit the method
attributes (__module__
, __name__
, __qualname__
,
__doc__
and __annotations__
) and have a new
__wrapped__
attribute.
Changed in version 3.11: Class methods can no longer wrap other
descriptors such as property()
.
This solution is only supported for a limited subset of python versions 3.9 and 3.10 and was buggy in those leading to it’s removal in 3.11. See the 3.11 deprecation notes (link) and the Github issue discussion (gh-89519).
I’m trying to set some default class variables in a base class so all subclasses are guaranteed to have a default value. Some of these I’d like to be dynamic based upon the subclass (DISPLAY_NAME
in the example below). The use of __qualname__
in _ExtensionBase
doesn’t work because it sets DISPLAY_NAME
to the static string "_ExtensionBase".
Is there a simpler way to do this, or any issues with the way I’ve found below? I haven’t stumbled into any, bit it feels like pushing some limits of the intended uses of property
and classmethod
class _ExtensionBase:
PRIORITY: float = 1.0
VERSION_STR: str = 'n/a'
@classmethod
@property
def DISPLAY_NAME(cls) -> str:
return cls.__name__
class ConcreteSubclass(_ExtensionBase): pass
assert ConcreteSubclass.DISPLAY_NAME == "ConcreteSubclass"
Try this:
ConcreteSubclass.__name__
Per the note in Python 3.11’s entry on @classmethod
(link)
Changed in version 3.9: Class methods can now wrap other descriptors
such asproperty()
.Changed in version 3.10: Class methods now inherit the method
attributes (__module__
,__name__
,__qualname__
,
__doc__
and__annotations__
) and have a new
__wrapped__
attribute.Changed in version 3.11: Class methods can no longer wrap other
descriptors such asproperty()
.
This solution is only supported for a limited subset of python versions 3.9 and 3.10 and was buggy in those leading to it’s removal in 3.11. See the 3.11 deprecation notes (link) and the Github issue discussion (gh-89519).