web-dev-qa-db-fra.com

Utilisation de variables pour les noms de classe en Python?

Je veux savoir comment utiliser des variables pour les objets et les noms de fonction en Python. En PHP, vous pouvez faire ceci:

$className = "MyClass";

$newObject = new $className();

Comment faites-vous ce genre de chose en Python? Ou est-ce que je n'apprécie pas du tout une différence fondamentale avec Python, et si oui, qu'est-ce que c'est?

38
Sam McAfee

En Python,

className = MyClass
newObject = className()

La première ligne fait que la variable className fait référence à la même chose que MyClass. Ensuite, la ligne suivante appelle le constructeur MyClass via la variable className.

À titre d'exemple concret:

>>> className = list
>>> newObject = className()
>>> newObject
[]

(En Python, list est le constructeur de la classe list.)

La différence est qu'en PHP, vous représentez le nom de la classe à laquelle vous voulez vous référer comme une chaîne, tandis qu'en Python vous pouvez référencer directement la même classe. Si vous devez utiliser une chaîne (par exemple si le nom de la classe est créé dynamiquement), alors vous devrez utiliser d'autres techniques.

24
Greg Hewgill

En supposant que some_module a une classe nommée "class_name":

import some_module
klass = getattr(some_module, "class_name")
some_object = klass()

Je dois noter que vous devez être prudent ici: transformer des chaînes en code peut être dangereux si la chaîne provient de l'utilisateur, vous devez donc garder à l'esprit la sécurité dans cette situation. :)

Une autre méthode (en supposant que nous utilisons toujours "class_name"):

class_lookup = { 'class_name' : class_name }
some_object = class_lookup['class_name']()  #call the object once we've pulled it out of the dict

Cette dernière méthode est probablement le moyen le plus sûr de le faire, c'est donc probablement ce que vous devez utiliser si possible.

55
Jason Baker

Si vous devez créer une classe dynamique dans Python (c'est-à-dire celle dont le nom est une variable), vous pouvez utiliser type () qui prend 3 paramètres: nom, bases, attrs

>>> class_name = 'MyClass'
>>> klass = type(class_name, (object,), {'msg': 'foobarbaz'})

<class '__main__.MyClass'>

>>> inst = klass()
>>> inst.msg
foobarbaz
  • Notez cependant que cela n'instancie pas l'objet (c'est-à-dire qu'il n'appelle pas de constructeurs, etc. Il crée une nouvelle classe (!) Du même nom.
23
coleifer

Si vous avez ceci:

class MyClass:
    def __init__(self):
        print "MyClass"

Ensuite, vous faites généralement ceci:

>>> x = MyClass()
MyClass

Mais vous pourriez aussi faire cela, et c'est ce que je pense que vous demandez:

>>> a = "MyClass"
>>> y = eval(a)()
MyClass

Mais, faites très attention à l'endroit où vous obtenez la chaîne sur laquelle vous utilisez "eval ()" - si elle provient de l'utilisateur, vous créez essentiellement un énorme trou de sécurité.

Mise à jour: L'utilisation de type() comme indiqué dans la réponse de coleifer est bien supérieure à cette solution.

8
TimB

J'utilise:

newObject = globals()[className]()
0
Yanone