2010-10-06 45 views
4

Je dois soit appeler exec() ou eval() basé sur une chaîne d'entrée "s"Python: comment savoir si une chaîne représente une instruction ou une expression?

Si "s" était une expression, après avoir appelé eval() je veux imprimer le résultat si le résultat n'était pas Aucun

Si "s" était une déclaration, alors simplement exec(). Si la déclaration arrive à imprimer quelque chose, alors qu'il en soit ainsi.

 
s = "1 == 2" # user input 
# --- 
try: 
    v = eval(s) 
    print "v->", v 
except: 
    print "eval failed!" 
# --- 
try: 
    exec(s) 
except: 
    print "exec failed!" 

Par exemple, "s" peut être:

 
s = "print 123" 

Et dans ce cas, exec() doit être utilisé.

Ofcourse, je ne veux pas essayer d'abord eval() et si elle échoue exec d'appel()

+0

Et si l'utilisateur entre un code malveillant? Et que peut * donner l'utilisateur en entrée (n'importe quel code Python, ou une langue "plus petite")? –

+0

Bonjour Bart, C'est à l'utilisateur de taper ce qu'il veut. Je viens de fournir un shell Python en utilisant ma propre interface utilisateur –

Répondre

10

Essayez de compile comme une expression. Si cela échoue, il doit s'agir d'une déclaration (ou juste invalide).

isstatement= False 
try: 
    code= compile(s, '<stdin>', 'eval') 
except SyntaxError: 
    isstatement= True 
    code= compile(s, '<stdin>', 'exec') 

result= None 
if isstatement: 
    exec s 
else: 
    result= eval(s) 

if result is not None: 
    print result 
+0

Bonne idée, merci bobince! –

6

Il semblerait que vous souhaitiez que l'utilisateur puisse interagir avec un interpréteur Python depuis votre script. Python permet à travers un appel à code.interact:

import code  
x=3 
code.interact(local=locals()) 
print(x) 

Exécution du script:

>>> 1==2 
False 
>>> print 123 
123 

Le intepreter est au courant des variables locales définies dans le script:

>>> x 
3 

L'utilisateur peut change également la valeur des variables locales:

>>> x=4 

Appuyer sur Ctrl-d renvoie le flux de contrôle au script.

>>> 
4  <-- The value of x has been changed. 
+0

Malheureusement, cette option n'est pas réalisable. Je fournis une boîte de saisie d'interface utilisateur simple pour l'utilisateur à taper la chaîne. –