2016-09-07 6 views
5

मेरे पास एक स्ट्रिंग अक्षर है जिसमें (विश्वसनीय) पायथन कोड की एक या अधिक पंक्तियां हैं, और मैं exec() ब्लॉक के परिणाम को कैप्चर करते समय ब्लॉक करना चाहता हूं अंतिम पंक्ति।पायथन: निष्पादन() कोड कोड और eval() अंतिम पंक्ति

code = """ 
x = 4 
y = 5 
x + y 
""" 

assert exec_then_eval(code) == 9 

कुछ बातें मैं कोशिश की है: अधिक वस्तुतः, मैं उस से ये एक समारोह चाहते हैं exec_then_eval

  1. अंतिम पंक्ति बंद बंटवारे से, आपको पहले ब्लॉक exec कर सकते हैं, फिर अंतिम पंक्ति eval; जैसे

    def exec_then_eval(code): 
        first_block = '\n'.join(code.splitlines()[:-1]) 
        last_line = code.splitlines()[-1] 
        globals = {} 
        locals = {} 
        exec(first_block, globals, locals) 
        return eval(last_line, globals, locals) 
    

    यह काम करता है, लेकिन आखिरी कथन में कई पंक्तियां विफल हो जाएंगी।

  2. यदि कोड स्वयं संशोधित किया गया है तो परिणाम स्थानीय चर के रूप में संग्रहीत किया जाता है, तो इस चर को फिर से पुनर्प्राप्त किया जा सकता है; जैसे

    code = """ 
    x = 4 
    y = 5 
    z = x + y 
    """ 
    
    globals = {} 
    locals = {} 
    exec(code, globals, locals) 
    assert locals['z'] == 9 
    

    फिर से, इस काम करता है, लेकिन केवल तभी जब आप पहली बार एक सामान्य तरीके से कोड ब्लॉक पार्स और इसे उचित रूप से संशोधित करने के लिए कर रहे हैं।

क्या सामान्य exec_and_eval फ़ंक्शन लिखने का कोई आसान तरीका है?

import ast 

def exec_then_eval(code): 
    block = ast.parse(code, mode='exec') 

    # assumes last node is an expression 
    last = ast.Expression(block.body.pop().value) 

    _globals, _locals = {}, {} 
    exec(compile(block, '<string>', mode='exec'), _globals, _locals) 
    return eval(compile(last, '<string>', mode='eval'), _globals, _locals) 

यह भी गुजरता है @ परीक्षण के vaultah के अच्छा सेट:

+0

मुझे नहीं लगता, यह करने के लिए एक आसान तरीका होगा करते ही आप कहीं का उपयोग कर प्राप्त करने में सक्षम हो सकता है https://docs.python.org/2/library/ast.html –

+0

आपके इनपुट को इस तरह दिखने का कोई विशेष कारण है? – user2357112

+0

डुप्लिकेट? http://stackoverflow.com/q/33908794/2301450 – vaultah

उत्तर

5

ast मॉड्यूल का उपयोग करने का @ kalzekdor के सुझाव के आधार पर, मैं इस समाधान जो @ vaultah के समाधान के लिए भावना में समान ऊपर तैनात है के साथ आया था मामलों:

exec_then_eval('''x = 4 
y = 5 
x + y''')) # 9 

exec_then_eval('''x = 4 
y = 5;x + y''')) # 9 

exec_then_eval('''x = 4 
y = 5;(
x + y * 

2)''') # 14 
+0

महान जवाब! आपको इसे स्वीकार करना चाहिए, मुझे निश्चित रूप से कोई फर्क नहीं पड़ता। – vaultah

+0

मुझे अभी एहसास हुआ कि यह एकमात्र सही उत्तर है, जो तब भी काम करता है जब अंतिम अभिव्यक्ति एक बहुभाषी स्ट्रिंग है। मेरा नहीं है, तो कृपया इसे अस्वीकार करें। – vaultah

+0

यदि आप जोर देते हैं! - – jakevdp

संबंधित मुद्दे