Comment convertir une chaîne de caractères à une fonction en python?
Par exemple, si j'ai une fonction appelée ajouter comme
def add(x,y):
return x+y
et je veux avoir la possibilité de convertir une chaîne de caractères ou une entrée directe à cette fonction comme
w=raw_input('Please input the function you want to use')
ou
w='add'
Est-il possible d'utiliser w pour désigner la fonction ajouter?
Vous devez vous connecter pour publier un commentaire.
Puisque vous prenez la saisie de l'utilisateur, le moyen le plus sûr est de définir exactement ce qui est valable d'entrée:
Si vous souhaitez évaluer les cordes, comme
'add(3,4)'
, vous pouvez utiliser coffre-fort eval:eval
en général pourrait être dangereux lorsqu'il est appliqué à une entrée d'utilisateur.Le dessus est plus sûr depuis__builtins__
est désactivé etlocals
est limité àdispatcher
. Quelqu'un de plus malin que je pourrais être en mesure de toujours causer des problèmes, mais je ne pourrais pas vous dire comment le faire.AVERTISSEMENT: Même
eval(..., {'__builtins__':None}, dispatcher)
est dangereux être appliqué à une entrée d'utilisateur. Un utilisateur malveillant pourrait exécuter des fonctions arbitraires sur votre machine si l'occasion est donnée d'avoir son string évalué pareval
.Un moyen sûr est à la carte à partir des noms de fonctions. Il est plus sûr que d'utiliser
eval
.NameError: name 'add' is not defined
ou si je neself.add()
(la version intégrale de l'appel de fonction), puis mon code de lit et exécute la fonction quand il est tentant de lire dans le dictionnaire! Toute réflexion sur la façon d'obtenir que cela fonctionne?def add(x, y): …
.add(1, 2)
serait un appel, de sorteadd
vous obtient l'objet appelable (une fonction), que vous pouvez ensuite appeler avecx(1, 2)
. Si vous voulez une méthode au lieu de cela, lorsque vous voulez écrireself.add(1, 2)
, puisself.add
vous obtient l'objet appelable (une méthode liée), etx(1, 2)
de les appeler. Si vous écrivez{'add': self.add()}
, ces parenthèses signifient que vous avez appelé la fonction, plutôt que de simplement référence à elle comme{'add': self.add}
ferait.unutbu la solution est ce que je voudrais l'utiliser normalement, mais par souci d'exhaustivité:
Si vous spécifiez le nom exact de la fonction, vous pouvez utiliser
eval
, même si elle est fortement déconseillée, car les gens peuvent faire des choses malveillantes:La fonction intégrée
eval
faire ce que vous souhaitez. Tous les habituelles mises en garde sur l'exécution arbitraire fourni par l'utilisateur code s'appliquent.Si il y a un nombre fini de fonctions prédéfinies, vous devriez éviter de
eval
et utiliser une table de recherche à la place (c'est à direDict
). Ne faites jamais confiance à vos utilisateurs.Si vous êtes à la mise en œuvre d'une coquille d'application où l'utilisateur d'entrer une autre commande (comme ajouter), et l'application réponses (retour à la somme), vous pouvez utiliser le
cmd
module qui gère l'ensemble de la commande interactions et l'expédition pour vous. Voici un exemple:Voici un exemple de session en cours d'exécution:
À l'invite (Cmd), vous pouvez émettre la
help
de commande que vous pouvez obtenir gratuitement. Les autres commandes sontadd
etquit
qui correspondent à lado_add()
etdo_quit()
fonctions.Notez que l'aide de la commande affiche la docstring de votre fonction. La docstring est une chaîne qui suit immédiatement la fonction declararation (voir
do_add()
par exemple).La
cmd
module ne prend pas en faire un argument crève, de l'analyse, de sorte que vous avez à faire vous-même. Ledo_add()
fonction en est une illustration.Cet exemple de programme devrait être assez pour vous obtenir a commencé. Pour plus d'informations consulter la cmd page d'aide. Il est de trivia pour personnaliser l'invite de commandes et d'autres aspects de votre programme.
Suffit d'utiliser la fonction de référence:
Simple et sécurisée.
J'ai eu beaucoup de situation où j'ai eu besoin de comparer une chaîne de type int, et vice-versa à l'intérieur d'un Django template.
J'ai créé un filtre qui m'a permis de réussir dans le nom de la fonction et l'utilisation de la fonction eval() de la convertir.
Exemple:
Modèle:
Modèle de Filtre (où j'utilise une chaîne d'appeler le nom de la fonction):
j'ai eu le même problème.
la façon dont je vous recommande de le gérer est de créer un temporaire python fichier pour stocker la fonction de l'entrée utilisateur. voici un exemple que j'ai utilisé dans un programme que j'ai écrit pour dessiner la représentation de fonctions mathématiques:
cela va créer un fichier contenant la fonction, je tiens à appeler
ensuite, vous devez appeler la fonction que vous avez écrit dans le fichier de votre programme :
vous pouvez désormais utiliser la fonction normale de la fonction python
si vous le souhaitez, vous pouvez également supprimer le dossier où vous avez enregistré votre fonction à l'aide d'os.supprimer:
pour vous aider à comprendre ici est mon programme pour tracer des fonctions mathématiques:
[Je suis arrivé ici via une double question. Ma première pensée a été d'utiliser
argparse
etshlex
et je ne vois pas qu'ici, je suis donc de l'ajouter comme une autre option.]Vous pouvez utiliser
argparse
de créer un registre de fonctions/commandes et en toute sécurité analyser leurs arguments. Cela permettra de fournir un certain niveau de convivialité aussi, par ex., vous permettant de savoir quand vous avez entré une commande qui n'existe pas.