Свойства Python также как свойства класса - PullRequest
2 голосов
/ 10 ноября 2010

У меня есть набор классов, которые могут содержать необязательный атрибут name. Причина в том, что классы получат имя по умолчанию, если атрибут установлен, но отдельные классы могут при необходимости иметь собственное имя.

То, что я хочу, - это возможность получить атрибут имени как из класса (без какого-либо экземпляра класса), так и из экземпляров класса.

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

Здесь класс A настраивает имя, а класс B - нет.

>>> a = A()
>>> a.name
'Class A'
>>> A.name
'Class A'

Как видно, все работает как надо

>>> b = B()
>>> b.name
'B'
>>> B.name
<property object at 0x7fd50a38c578>

Это не работает, как я хочу! Получение имени из определенного экземпляра работает как следует, но попытка получить имя из класса возвращает property object.

Можно ли получить имя непосредственно из класса, не перепрыгивая через обручи с объектом свойства (который я действительно не могу проверить в том месте, где мне нужен атрибут класса в любом случае.)

Ответы [ 2 ]

1 голос
/ 10 ноября 2010
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
0 голосов
/ 10 ноября 2010

Я не уверен, работает ли здесь ваш класс NameMixin.

В первом случае name является свойством класса и может быть доступно так же, как вы говорите.

>>> class A():
...     name = 'Class A'
... 
>>> 
>>> a = A()
>>> a.name
'Class A'
>>> A.name
'Class A'
>>> 

Во втором случае класс NameMixin возвращает свойство, как вы предложили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...