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"
Asked By: JCowfer

||

Answers:

Try this:

ConcreteSubclass.__name__
Answered By: zalevskiaa

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).

Answered By: JCowfer
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.