2010-12-08 41 views
3

J'écris un programme pour calculer le volume d'un solide de rotation. La première étape consiste à calculer une intégrale. J'utilise scipy.integrate pour cela, mais je ne peux pas trouver la meilleure façon d'avoir une équation (comme x=x**2 entrée à la ligne de commande.Je prévoyais à l'origine l'ajout d'un argument 'par rapport à: x | y' et ensuite en prenant la fonction en tant que lambda. Malheureusement, argparse ne prendra pas lambda comme type d'argument, et d'essayer d'utiliser une chaîne pour construire un lambda (f = lambda x: args.equation) retourne juste une chaîne (compréhensible vraiment).Comment prendre une fonction comme argument? (Python)

Voici ce que je ve obtenu jusqu'à présent:

import sys 
import argparse 
import math 
from scipy import integrate 

parser = argparse.ArgumentParser(description='Find the volume of the solid of rotation defined') 
parser.add_argument('equation', help='continous function') 
parser.add_argument('a', type=float, help='bound \'a\'') 
parser.add_argument('b', type=float, help='bound \'b\'') 
parser.add_argument('-axis', metavar='x|y', help='axis of revolution') 
args = parser.parse_args() 

def volume(func, a, b, axis=None): 
    integral = integrate.quad(func, a, b) 
    return scipy.py * integral 

print volume(args.equation, args.a, args.b) 

Tout conseil sera apprécié grâce

Répondre

6

S'il n'y a absolument aucun problème sur les risques de sécurité de laisser couler l'utilisateur du code Python arbitraire, vous pouvez utiliser eval pour créer un objet appelable:

volume(eval('lambda x: %s' % args.equation), args.a, args.b) 
+0

merci. Y a-t-il aussi un moyen plus sûr? –

+1

Pour être "sûr", vous devez documenter exactement les constructions que vous voulez autoriser, et écrire un analyseur. C'est beaucoup de travail. –

2

Vous devriez pouvoir utiliser eval() sur la chaîne que vous obtenez de vos arguments:

>>> f = eval("lambda x: x**2") 
>>> f(5) 
25