2012-10-02 26 views
8

मैं निम्नलिखित टैब-इंडेंट स्ट्रिंग eval करने का प्रयास कर रहा हूँ:पाइथन का eval() इस multiline स्ट्रिंग को अस्वीकार क्यों कर रहा है, और मैं इसे कैसे ठीक कर सकता हूं?

'''for index in range(10): 
     os.system("echo " + str(index) + "") 
''' 

मैं मिलता है, "करने में त्रुटि हुई: अवैध वाक्य रचना, लाइन 1"

क्या इसके बारे में शिकायत कर रहा है? क्या मुझे eval() कथन से मेल करने के लिए इंडेंट करने की आवश्यकता है, या इसे स्ट्रिंग फ़ाइल या अस्थायी फ़ाइल में लिखना है और इसे निष्पादित करना है, या कुछ और?

धन्यवाद,

उत्तर

20

eval का मूल्यांकन करता है की तरह 5+3

exec सामान 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

ओह। आपका जवाब यहाँ था! इसे डुप्ली के रूप में चिह्नित किया जाना चाहिए था: पी –

+0

lol मैं इसके बारे में सब भूल गया: पी –

+0

मैंने इसे http: // stackoverflow से पकड़ा।कॉम/प्रश्न/30671563/eval-not-working-on-multi-line-string # comment49405263_30671563: डी –

11

की तरह सामान कार्यान्वित eval साथ इस तरह के बयानों का उपयोग करने के लिए आपको सबसे पहले कोड वस्तु के लिए उन्हें बदलने चाहिए, compile() का उपयोग कर:

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

हमेशा एक अच्छा उत्तर और पायथन की एक विशेषता के रूप में मुझे पता नहीं था :) –

5

हम मूल्यांकन (eval) अभिव्यक्तियों का मूल्यांकन करते हैं, और निष्पादन (exec) कथन।

देखें: 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

(इससे पहले कि आप उत्पादन में इस तरह कोड डाल अंत में डिफ़ॉल्ट सुरक्षा चेतावनी मिलते हैं!)

अन्य उत्तर exec और eval के बीच अंतर समझाने का एक अच्छा काम करते हैं।

फिर भी, मैं अपने आप को x=1; y=2; x+y तरह इनपुट लेने के लिए बल लोग लिखने के बजाय चाहने पाया: समारोह की इस तरह के निर्माण के लिए कोड की

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

स्ट्रिंग हेरफेर एक जोखिम भरा काम है।

मैं निम्नलिखित दृष्टिकोण का उपयोग कर समाप्त हो गया:

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) 

यह अजगर कोड को पार्स करता है; अंतिम पंक्ति के अलावा सब कुछ के एक अस्थिर पुनर्निर्माण के लिए अस्थ पुस्तकालय का उपयोग करता है; और आखिरी पंक्ति, पूर्व को निष्पादित करने और बाद में eval'ing।

सुरक्षा चेतावनी

यह अनिवार्य सुरक्षा चेतावनी आप eval को संलग्न करने के लिए होता है। Eval 'आईएनजी और exec' गैर-विशेषाधिकार प्राप्त उपयोगकर्ता द्वारा प्रदान किया गया आईएनजी कोड निश्चित रूप से असुरक्षित है। इन मामलों में आप किसी अन्य दृष्टिकोण का उपयोग करना पसंद कर सकते हैं, या ast.literal_eval पर विचार कर सकते हैं। eval और exec खराब विचार हैं जब तक कि आप वास्तव में अपने उपयोगकर्ता को पाइथन की पूर्ण अभिव्यक्ति शक्ति नहीं देना चाहते हैं।