Pouvez-vous utiliser une chaîne à instancier une classe?
Je suis en utilisant un générateur de modèle pour séparer un tas de différentes possibilités de configuration. En gros, j'ai un tas de classes qui sont nommés d'un ID (quelque chose comme ID12345). Ces héritent toutes de la base de constructeur de classe. Dans mon script, j'ai besoin d'instancier une instance de chaque classe (environ 50) chaque fois que cette application s'exécute. Donc, je suis en train de voir si, au lieu de faire quelque chose comme ceci:
ProcessDirector = ProcessDirector()
ID12345 = ID12345()
ID01234 = ID01234()
ProcessDirector.construct(ID12345)
ProcessDirector.construct(ID01234)
ID12345.run()
ID01234.run()
Puis-je faire quelque chose comme ça (je sais que cela ne fonctionne pas):
IDS = ["ID12345", "ID01234"]
ProcessDirector = ProcessDirector()
for id in IDS:
builder = id() #some how instantiate class from string
ProcessDirector.construct(builder)
builder.run()
De cette façon, quand j'ai besoin d'ajouter un nouveau dans le futur, tout ce que j'ai à faire est d'ajouter l'id de l'ID de liste, plutôt que de les émaillant le nouvel ID dans le code.
MODIFIER
Ressemble à il ya quelques opinions différentes sur la base où les données proviennent de. Ces Identifiants sont entrées dans un fichier que personne d'autre n'a accès. Je ne suis pas la lecture de la les chaînes à partir de la ligne de commande, et je voudrais être en mesure de faire aussi peu de modifications lors de l'ajout d'un nouveau code dans le futur.
- Ces ID classes dans le même fichier que la boucle, ou voulez-vous de les importer à partir de quelque part d'autre?
- Dupliquer: stackoverflow.com/questions/452969/...
- ce n'est pas un doublon de cela, c'est un python question, pas un code java, la question que vous l'avez mentionné est demander si une fonction existe en python qui existe en java avec peu d'explication derrière elle, rappelez-vous que la question est de savoir comment les gens trouvent qu'il, pas les réponses donc, juste parce que il existe une réponse à l'autre question qui peut répondre à ça ne veut pas dire que les gens vont le trouver, à moins qu'ils pensent de la question en termes de java comme l'OP de la question.
Vous devez vous connecter pour publier un commentaire.
Pas sûr que c'est ce que vous voulez, mais il semble comme une plus Pythonic façon d'instancier un tas de classes inscrites dans une chaîne de caractères:
IDS
la liste est juste un exemple, il pourrait venir de n'importe où (fichier, etc)class car():\r\n def __init__(self): pass
instancié comme ['ford', 'toyota', 'vw'] Dans construct() vous pourriez fairesetattr(self,builderName,idClasses())
. De cette façon, vous vous retrouvez avec le directeur.ford, directeur.toyota, et directeur.vw objets.Si vous voulais éviter un eval(), vous pouvez simplement faire:
À condition que la classe est définie dans (ou importés) votre portée.
abc
pour générer dynamiquement une instance de toutes les sous-classes d'une classe de base.globals()[classname_string]()
toujours une bonne façon d'instancier un objet donné que le nom de la classe comme une chaîne de caractères? Toujours parce que je suis en posant la question, près de 8 ans après l'original de la réponse.Jamais utilisation
eval()
si vous pouvez l'aider. Python a donc beaucoup de meilleures options d'expédition dictionnaire,getattr()
, etc.) que vous ne devriez jamais avoir à utiliser la faille de sécurité connue commeeval()
.Façon la plus simple est de créer un dict.
Puis utilisez (votre exemple de code):
namedclass
doit venir après toutes les classes qu'elle les listes. Django utilise également des cordes pour se référer à des modèles non encore défini.J'ai décidé de mettre ensemble les accepté de répondre à et un commentaire sur la accepté de répondre. j'ai également ajouté de la surcharge
__getitem__
donc, cela ressemble plus à une usine modèle.Édité: j'ai ajouté une gestion d'erreur.
Édité: Placé sous permissive de la licence Creative Commons. Profitez de.
Il y a quelques trucs qui manque dans votre question, donc, je suis obligé d'en deviner l'omis des choses. N'hésitez pas à modifier votre question à corriger les omissions.
Cela fonctionne très bien. Il n'a pas d'instancier à partir d'une chaîne -- dans la pratique, vous n'avez pas envie de cela. Parfois, mais rarement. Le plus souvent, vous une liste d'objets de la classe à partir de laquelle vous souhaitez que les objets d'instance.
Si vous êtes l'obtention de votre classe des noms à partir de la ligne de commande, vous devez alors faire le petit changement.
Tout le reste est le même.
[Également, si possible, essayez de démarrer exemple les noms de variables avec des lettres minuscules. Les noms qui commencent par une Majuscule sont généralement des noms de classe.]
Modifier
Retiré
eval
. En dépit du fait queeval()
est absolument pas un trou de sécurité. Eval (etexec
etexecfile
) sont uniquement un problème si une personne en particulier accorde l'accès à des utilisateurs malveillants.