2009-04-09 6 views
1

Comment utiliser une chaîne contenant un nom de classe pour référencer une classe elle-même?
Voir ce (ne fonctionne pas) ... exemplePython: référence à une classe à partir d'une chaîne?

class WrapperClass: 
    def display_var(self): 
     #FIXME: self.__class_name__.__name__ is a string 
     print self.__class__.__name__.the_var 

class SomeSubClass(WrapperClass): 
    var = "abc" 

class AnotherSubClass(WrapperClass): 
    var = "def" 

Et un message d'erreur évidente:

 
>>> b = SomeSubClass() 
>>> b.display_var() 
Traceback (most recent call last): 
    File "", line 1, in 
    File "", line 4, in display_var 
AttributeError: 'str' object has no attribute 'the_var' 
>>> 

Merci!

Répondre

5

Comment utiliser une chaîne contenant un nom de classe pour faire référence à une classe elle-même

classes ne sont pas spéciaux, ils sont juste des valeurs contenues dans les variables Si vous avez dit:.

class X(object): pass 

Dans la portée globale, la variable 'X' sera une référence à l'objet de classe.

Vous pouvez obtenir les variables globales de script en cours/module comme dictionnaire à l'aide « globals() », donc:

classobj= globals()[self.__class__.__name__] 
print classobj.var 

(locals() est également disponible pour les variables locales, entre eux vous ne devriez pas avoir besoin . utiliser le eval() terrible pour accéder aux variables)

Cependant, comme le note David, self.__class__ est déjà le classobj, donc il n'y a pas besoin d'aller courir l'aller chercher des variables globales par son nom; self.__class__.var va bien. Bien que vraiment:

print self.var 

serait le moyen simple habituel de le faire. Les membres de classe sont disponibles en tant que membres de leurs instances, tant que l'instance ne remplace pas le nom par quelque chose d'autre.

+0

+1 bien expliqué –

+0

hmmm: "la variable 'X' sera une référence" Pas précisément. L'identificateur "X" est l'objet de classe lui-même, et peut être utilisé partout où une constante serait utilisée. –

+0

En effet. Ce que j'essaie de décrire dans un anglais maladroit, c'est que tandis que X est l'objet de classe, c'est juste une référence; Si vous avez assigné quelque chose d'autre à "X" alors ce ne sera plus le cas. Le point important est que dans Python, le nom 'X' ne devient pas spécial; c'est juste une autre variable. – bobince

1

Votre exemple fonctionnerait si vous appeliez print self.__class__.var. Je ne pense pas qu'il soit nécessaire d'utiliser le nom.

+0

Haha, c'est logique! Merci beaucoup. – Orphee

+0

Apparemment non, pourquoi demanderait-il s'il connaissait la réponse? –

2

Selon l'endroit où vous obtenez cette chaîne, une méthode générale peut être non sécurisée (une telle méthode consiste à utiliser simplement eval(string) La meilleure méthode consiste à définir un nom de mappage dict aux classes.

class WrapperClass: 
    def display_var(self): 
     #FIXME: self.__class_name__.__name__ is a string 
     print d[self.__class__.__name__].the_var 

class SomeSubClass(WrapperClass): 
    the_var = "abc" 

class AnotherSubClass(WrapperClass): 
    the_var = "def" 

d = {'WrapperClass': WrapperClass, 'SomeSubClass': SomeSubClass, 'AnotherSubClass': AnotherSubClass} 
AnotherSubClass().display_var() 
# prints 'def' 
Questions connexes