Reputation: 409482
I have a set of classes which can contain an optional name
attribute. The reason is that the classes will get a default name if the attribute is set, but individual classes can still have a custom name if needed.
What I want is to be able to get the name attribute from both the class (without any class instance) and from instances of a class.
class NameMixin(object):
def _get_name(self):
if getattr(self, '_name', ''):
return self._name
else:
return self.__class__.__name__
def _set_name(self, name):
self._name = name
name = property(_get_name, _set_name)
class A(NameMixin):
name = 'Class A'
class B(NameMixin):
pass
Here, the class A
customizes the name, while class B
does not.
>>> a = A()
>>> a.name
'Class A'
>>> A.name
'Class A'
As seen, this works as it should
>>> b = B()
>>> b.name
'B'
>>> B.name
<property object at 0x7fd50a38c578>
This does not work as I want! Getting the name from a specific instance works as it should, but attempting to get the name from the class returns a property object
.
Is it possible to get the name directly from a class without jumping through hoops with the property object (which I really can't check for in the place where I need the class-attribute anyway.)
Upvotes: 2
Views: 216
Reputation: 304473
class NameMixinMeta(type):
def _get_name(self):
return getattr(self, '_name', self.__name__)
def _set_name(self, name):
self._name = name
name = property(_get_name, _set_name)
class NameMixin(object):
__metaclass__ = NameMixinMeta
def _get_name(self):
return getattr(self, '_name', self.__class__.__name__)
def _set_name(self, name):
self._name = name
name = property(_get_name, _set_name)
class A(NameMixin):
_name = 'Class A'
class B(NameMixin):
pass
Upvotes: 1
Reputation: 66739
I am not sure if your NameMixin class is at work here.
In the first case, name is a class property and can be accessed just like you say.
>>> class A():
... name = 'Class A'
...
>>>
>>> a = A()
>>> a.name
'Class A'
>>> A.name
'Class A'
>>>
In the second case the NameMixin class has the effect of returning the property as you suggested.
Upvotes: 0