2013-08-23 5 views
0

Mon exigence est d'utiliser la valeur de variable pour référencer classe/dictionnaires en Python. A titre d'exemple échantillon, j'ai données suivantes: -Utilisation de la valeur de la variable en tant que dictionnaire/nom de classe en Python

class test1: 
    pass 

class test2: 
    pass 

test1_dict = {} 
test2_dict = {} 

testvariable = "test1" 

Maintenant, je veux vérifier la valeur de testvariable et créer une instance de la classe et l'ajouter dans le dictionnaire.

par exemple.

if testvariable == "test1": 
    test1inst = test1() 
    test1_dict["test1"] = test1inst 
elif testvariable == "test2": 
    test2inst = test2() 
    test2_dict["test2"] = test2inst 

Dans le code ci-dessus, je dois utiliser explicitement if/else pour vérifier la valeur de testvariable et effectuer les opérations en conséquence.

Dans mon scénario réel, je pourrais avoir plusieurs valeurs de testvariable et il pourrait y avoir plusieurs endroits où la vérification if/else serait requise. Donc, est-il possible que d'une manière ou d'une autre, je puisse utiliser la valeur de testvariable directement pour référencer des instances de dictionnaire/classe sans utiliser if/else.

+0

Voir ici: http://stackoverflow.com/questions/452969/does-python-have-an -equivalent-to-java-class-forname –

+0

Quelle est l'erreur que vous obtenez? – thefourtheye

+0

Je l'ai, je dois utiliser dict et ses méthodes pour gérer les données. Corrigé, merci. – sarbjit

Répondre

9

Il est presque jamais une bonne raison de rechercher des noms comme ceci. Python a une structure de données parfaitement bonne pour mapper les noms aux objets, et c'est un dict. Si jamais vous vous trouvez en train de dire "J'ai besoin d'une recherche dynamique de quelque chose", alors une dict est la réponse. Dans votre cas:

from collections import defaultdict 
test_classes = { 
    'test1': test1, 
    'test2': test2 
} 
test_instances = defaultdict(list) 
test_instances[testvariable].append(test_classes[testvariable]) 
+0

Je suis d'accord avec vous, mais je suis confronté à des problèmes de mise en œuvre de la même chose dans mon code actuel. S'il vous plaît voir mon édition, qui représente mon problème réel de plus près. – sarbjit

0

Je suis d'accord avec Daniel Roseman qu'il ya presque jamais une bonne raison de le faire. Cependant, je suis prêt à relever un défi! Le PO suit mon exemple à ses risques et périls.

Le secret est d'utiliser la fonction exec de Python, ce qui permet d'exécuter le contenu d'une chaîne code Python:

Ainsi,

if testvariable == "test1": 
    test1inst = test1() 
    test1_dict["test1"] = test1inst 
elif testvariable == "test2": 
    test2inst = test2() 
    test2_dict["test2"] = test2inst 

devient

exec("%sinst = %s()" % (testvariable, testvariable)) 
exec("%s_dict[testvariable] = %sinst" % (testvariable, testvariable)) 

mais avec la mise en garde les autres valeurs de testvariable ne font rien dans le cas d'OP, et dans le cas où exec() aboutit à des exceptions NameError.

+0

Non, mauvaise idée. Vous pouvez faire la même chose en recherchant la classe dans les variables locales ou les variables globales: inst = locals() [testvariable] – daveydave400

+0

Très vrai, bien que cette méthode ne nécessite pas de test d'où elle vient dans la portée. En outre, je pense que ma réponse a clairement indiqué que c'était une mauvaise idée de le faire. :) –

+1

Oui, je viens de voir "exec" et je suis allé dans un endroit très sombre. :) – daveydave400

0

Je vais combiner d'autres messages et dire que Python a déjà un dictionnaire qui mappe les noms des objets à l'objet. Vous pouvez accéder à des variables locales et globales afin que votre classe est définie dans le module que vous pouvez faire:

my_inst[testvariable] = locals()[testvariable]() 
Questions connexes