2010-11-10 6 views
2

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

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

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.

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

ответ

1
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

Хм ... Почти работает ... A.name возвращает «A», что не совсем правильно. Однако ваше использование метакласса заставило меня задуматься, и похоже, что я получил решение, которое работает. Я просто пропущу свойства и mixins, а в метаклассе я переопределю '__new__' и добавлю« имя »в словарь, если его там нет. –

0

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

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

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

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

Смежные вопросы