In an instance method of a python class, I know that we can get the class name via self.__class__.__name__
However, I'd like to store the name of a class in a class variable, without coding the name of the class.
I know I can do this to get a class's name into a class variable:
class MyClass(object):
pass
MyClass._myname = MyClass.__name__
However, I have to code the string MyClass
two times outside of the class definition, simply to get the class name into a class variable. In this case, that would be "MyClass"
, which I could simply code as follows:
class MyClass(object):
_myname = "MyClass"
But even that is redundant, given that I have to hard-code "MyClass"
within the MyClass
class.
What I'd like is to somehow get a class's name into a class variable without coding the class's name, as follows:
class MyClass(object):
_myname = ???? # where ???? is a statement which returns the class
# name, in which the string "MyClass" does not appear
Is this even possible?
You could use a decorator
>>> def autoname(cls):
... cls._MyName=cls.__name__
... return cls
...
>>> @autoname
... class check:
... pass
...
>>> check._MyName
'check'
>>>
Or if you do not want to hard-code the name of the attribute:
>>> def autoname2(name):
... def autoname(cls):
... setattr(cls, name, cls.__name__)
... return cls
... return autoname
...
>>> @autoname2('_StoreHere')
... class check2:
... pass
...
>>> check2._StoreHere
'check2'
>>>
Of course, the second form can take more parameters, for example:
>>> def autoname3(name, f=lambda x: x):
... def autoname(cls):
... setattr(cls, name, f(cls.__name__))
... return cls
... return autoname
...
>>> @autoname3('_MyNameIs', lambda x: x.upper() + '_The_Bold')
... class check3:
... pass
...
>>> check3._MyNameIs
'CHECK3_The_Bold'
>>>
A note on decorator vs metaclass: Metaclasses are seriously cool, nonetheless, if one doesn't strictly need them they are better avoided because of the infamous metaclass conflicts.