2010-11-10 9 views
2

J'ai un ensemble de classes pouvant contenir un attribut optionnel name. La raison en est que les classes recevront un nom par défaut si l'attribut est défini, mais les classes individuelles peuvent toujours avoir un nom personnalisé si nécessaire. Ce que je veux, c'est pouvoir obtenir l'attribut name à la fois de la classe (sans aucune instance de classe) et des instances d'une classe.Propriétés Python également en tant que propriétés de classe

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 

Ici, la classe A personnalise le nom, alors que la classe B ne fonctionne pas.

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

Comme on le voit, cela fonctionne comme il se doit

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

Cela ne fonctionne pas comme je veux! Obtenir le nom d'une instance spécifique fonctionne comme il se doit, mais tenter d'obtenir le nom de la classe renvoie un property object.

Est-il possible d'obtenir directement le nom d'une classe sans sauter à travers des cerceaux avec l'objet de propriété (que je ne peux pas vérifier dans l'endroit où je besoin de la classe attribut de toute façon.)

Répondre

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

Hmm ... Fonctionne presque ... A.name renvoie 'A' ce qui n'est pas tout à fait correct. Cependant, votre utilisation d'une métaclasse m'a fait réfléchir, et il semble que j'ai une solution qui fonctionne. Je passerai juste les propriétés et les mixins, et dans la métaclasse je remplacerai '__new__' et ajouterai 'name' au dictionnaire s'il n'y est pas. –

0

I Je ne suis pas sûr si votre classe NameMixin est au travail ici. Dans le premier cas, name est une propriété de classe et peut être accédé comme vous le dites.

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

Dans le second cas, la classe NameMixin a pour effet de renvoyer la propriété comme vous l'avez suggéré.

Questions connexes