Some programmer dude
Some programmer dude

Reputation: 409482

Python properties also as class properties

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

Answers (2)

John La Rooy
John La Rooy

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

pyfunc
pyfunc

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

Related Questions