2012-10-02 3 views
8

Aşağıdaki sekme girintili dize eval çalışılıyor o şikayet nedirNeden Python'un eval() öğesi bu çok satırlı dizeyi reddediyor ve bunu nasıl düzeltebilirim? "Bir hata oluştu: geçersiz sözdizimi, çizgi 1",</p> <pre><code>'''for index in range(10): os.system("echo " + str(index) + "") ''' </code></pre> <p>alıyorum:

? Eval() ifadesini eşleştirmek için indekslemeli veya bir dize dosyasına veya geçici dosyaya yazıp bunu çalıştırmalı mıyım yoksa başka bir şey mi yapmalıyım?

sayesinde

cevap

20

eval5+3

exec gibi şeyler compile() kullanarak, önce kod nesnesine dönüştürmek gerekir eval böyle ifadeleri kullanmak için for ...

>>> eval("for x in range(3):print x") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<string>", line 1 
    for x in range(3):print x 
    ^
SyntaxError: invalid syntax 
>>> exec("for x in range(3):print x") 
0 
1 
2 
>>> eval('5+3') 
8 
+0

Hata. Cevabınız buradaydı! Bunu dupe olarak işaretlemeliyiz: P –

+0

lol Tüm bunları unutmuştum: P –

+0

Bunu http: // stackoverflow'dan yakaladım.com/questions/30671563/eval-not-not-working-on-multi-line-string # comment49405263_30671563: D –

11

gibi şeyler yürütür değerlendirir:

In [149]: import os 

In [150]: cc = compile('''for index in range(10): 
    os.system("echo " + str(index) + "")''','abc','single') 

In [154]: eval cc 
--------> eval(cc) 
0 
Out[154]: 0 
1 
Out[154]: 0 
2 
Out[154]: 0 
3 
Out[154]: 0 
4 

In [159]: cc = compile("2+2", 'abc', 'single') # works with simple expressions too 

In [160]: eval cc 
--------> eval(cc) 
Out[160]: 4 


>>> help(compile) 

compile(...) 
    compile(source, filename, mode[, flags[, dont_inherit]]) -> code object 

    Compile the source string (a Python module, statement or expression) 
    into a code object that can be executed by the exec statement or eval(). 
    The filename will be used for run-time error messages. 
    The mode must be 'exec' to compile a module, 'single' to compile a 
    single (interactive) statement, or 'eval' to compile an expression. 
    The flags argument, if present, controls which future statements influence 
    the compilation of the code. 
    The dont_inherit argument, if non-zero, stops the compilation inheriting 
    the effects of any future statements in effect in the code calling 
    compile; if absent or zero these statements do influence the compilation, 
    in addition to any features explicitly specified. 
+2

her zaman iyi bir cevap ve python bir özelliği olarak farkında değildim :) –

5

(eval) ifadelerini değerlendirir ve (exec) ifadelerini yürütün.

Bak: Expression Versus Statement.

Expression: Something which evaluates to a value. Example: 1+2/x
Statement: A line of code which does something. Example: GOTO 100

2

(Eğer üretime böyle bir kod koymadan önce sonundaki varsayılan güvenlik uyarısı bakın!)

diğer cevaplar exec ve eval arasındaki farkı açıklayan iyi bir iş yapmak.

Yine de kendimi kuvvet insanlar yazmak için yerine x=1; y=2; x+y gibi girdi almak isteyen bulundu: kodun

def f(): 
    x = 1 
    y = 2 
    return x + y 

dize manipülasyon işlevi bu tür inşa etmek riskli bir iştir.

Ben aşağıdaki yaklaşımı kullanarak sona erdi:

def multiline_eval(expr, context): 
    "Evaluate several lines of input, returning the result of the last line" 
    tree = ast.parse(expr) 
    eval_expr = ast.Expression(tree.body[-1].value) 
    exec_expr = ast.Module(tree.body[:-1]) 
    exec(compile(exec_expr, 'file', 'exec'), context) 
    return eval(compile(eval_expr, 'file', 'eval'), context) 

Bu piton kodunu ayrıştırır; Son satırdan ayrı bir şeyleri yeniden inşa etmek için ast kütüphanesini kullanır; ve son satır, eskiyi yürütmek ve daha sonra değerlendirmek.

Bu eval eklemek zorunda zorunlu güvenlik uyarısıdır Güvenlik uyarısı. Ayrıcalıklı olmayan bir kullanıcı tarafından sağlananEval 've exec' kodları elbette güvensizdir. Bu durumlarda başka bir yaklaşım kullanmayı veya ast.literal_eval'ı kullanmayı tercih edebilirsiniz.ve exec, kullanıcılarınıza gerçek anlamda python'un tam ifade gücünü vermek istemediğiniz sürece kötü fikirler olma eğilimindedir.

İlgili konular