Python ont un équivalent à la Classe Java.forName()?
J'ai le besoin de prendre un argument de type chaîne et de créer un objet de la classe nommés dans cette chaîne de caractères en Python. En Java, je voudrais utiliser Class.forName().newInstance()
. Est-il un équivalent en Python?
Merci pour les réponses. Pour répondre à ceux qui veulent savoir ce que je fais: je veux utiliser un argument de ligne de commande le nom de la classe, et de l'instancier. Je suis tout à fait de la programmation en Python et l'instanciation des classes Java, d'où la Java " de la question. getattr()
fonctionne très bien. Merci beaucoup.
- Voir stackoverflow.com/a/10675081/116891 pour un exemple d'utilisation de
importlib.import
, qui a été reporté à partir de python 3 à 2,7 (docs.python.org/2/library/importlib.html)
Vous devez vous connecter pour publier un commentaire.
Réflexion en python est beaucoup plus facile et beaucoup plus souples que c'est en Java.
Je vous recommande la lecture de ce tutoriel
Il n'y a pas de fonction directe (que je connais) qui prend un nom de classe entièrement qualifié et retourne la classe, cependant, vous avez toutes les pièces nécessaires à la construction, et vous pouvez les connecter entre eux.
Un petit conseil cependant: n'essayez pas de programmer en Java de style lorsque vous êtes en python.
Si vous pouvez expliquer qu'est-ce que vous êtes en train de faire, peut-être nous pouvons vous aider à trouver un plus pythonic façon de faire.
Voici une fonction qui fait ce que vous voulez:
Vous pouvez utiliser la valeur de retour de cette fonction, comme si c'était la classe elle-même.
Voici un exemple d'utilisation:
Comment cela fonctionne?
Nous utilisons
__import__
importer le module qui contient la classe, qui a exigé que nous avons d'abord extraire le nom du module à partir du nom complet. Ensuite, nous importons le module:Dans ce cas,
m
ne fait référence qu'à haut niveau module,Par exemple, si votre classe vit dans
foo.baz
module, puism
sera le modulefoo
Nous pouvons facilement obtenir une référence à
foo.baz
à l'aide degetattr( m, 'baz' )
Pour obtenir à partir du niveau supérieur du module de la classe, ont récursive de l'utilisation
gettatr
sur les parties du nom de la classeDire par exemple, si vous avez un nom de classe est
foo.baz.bar.Model
puis nous faisons cela:C'est ce qui se passe dans cette boucle:
À la fin de la boucle,
m
sera une référence à la classe. Cela signifie quem
est en fait la classe itslef, vous pouvez le faire par exemple:__import__
__import__
existe. Des projets comme Django qui n'module de chargement de la magie de l'utiliser tout le temps. Belle réponse.get_class = lambda name: reduce(getattr, name.split('.')[1:], __import__(name.partition('.')[0]))
. Bien que la notion " d'objet.from_name' pourrait être un meilleur nom. Exemples: get_class('virgule.Virgule'), get_class(nom du module).type
- je obtenir unclassobj
. Des idées pourquoi? et comment puis-je réellement obtenir une instance de cette classe à partir d'elle?get_class
àreturn m()
.En supposant que la classe est à votre portée:
Autrement:
Edit: Remarque, vous ne pouvez pas donner un nom comme 'foo.le " bar à getattr. Vous aurez besoin de le diviser par . et appel getattr() sur chaque pièce de gauche à droite. Cela permettra de poignée:
attrs = 'foo.bar.baz'.split('.'); fooBar = reduce(getattr, attrs[1:], __import__(attrs[0]))
module, _, attrs = 'foo.bar.baz'.partition('.'); fooBar = reduce(getattr, attrs, __import__(module))
Utilisation
Encore une autre mise en œuvre.
if module_name
LBYL est assez devenus inutiles, car l'erreur que vous obtenez tout simplement si vous supprimez ces lignes est:ValueError: Empty module name
.Il semble que vous vous approchez de ce partir du milieu au lieu du début. De quoi êtes-vous vraiment essayer de faire? Trouver la classe associée à une chaîne de caractères est un moyen pour une fin.
Si vous préciser votre problème, qui pourrait avoir besoin de votre propre mental refactoring, une meilleure solution peut présenter lui-même.
Par exemple: Êtes-vous essayer de charger une version sauvegardée de l'objet en fonction de son type nom et un ensemble de paramètres? Python sorts de cette unpickling et vous devriez regarder la module pickle. Et même si le unpickling processus est exactement ce que vous décrivez, vous n'avez pas à vous soucier de la façon dont il fonctionne en interne:
Cela est le python de la bibliothèque standard, comme unittest.TestLoader.loadTestsFromName. Malheureusement, la méthode va faire de test d'activités connexes, mais cette première ha semble ré-utilisable. J'ai édité pour supprimer le test des fonctionnalités: