2016-12-19 7 views
7

क्यों पाइथन का eval फ़ंक्शन के अंदर काम नहीं करता है? एक ही eval(compile(cmd)) कोड वैश्विक वातावरण में काम करता है, लेकिन foo फ़ंक्शन के अंदर काम नहीं करता है।पायथन eval फ़ंक्शन के अंदर काम नहीं करता

सरल उदाहरण:

fn = '/tmp/tmp' 
mode = 'single' 

def foo(cmd, fn, mode): 
    eval(compile(cmd, fn, mode)) # <<< this does not work 
    print 'foo: cmd=', cmd 
    print 'foo: x=', x 

cmd = "x = 1" 
eval(compile(cmd, fn, mode)) # <<< this works 
print 'global scope: cmd=', cmd 
print 'global scope: x=', x 

del(x) 
foo('x = 9', fn, mode) 

यह आउटपुट और त्रुटि संदेश है:

global scope: cmd= x = 1 
global scope: x= 1 
foo: cmd= x = 9 
foo: x= 
Traceback (most recent call last): 
    File "ctest.py", line 20, in <module> 
    foo('x = 9', fn, mode) 
    File "ctest.py", line 12, in foo 
    print 'foo: x=', x 
NameError: global name 'x' is not defined 
+0

क्या आप वाकई कुछ करने के लिए अपने मूल्य आवंटित करने के लिए नहीं करना चाहते हैं? –

+0

बस यह कोशिश की: 'x'' लोकल 'dict में समाप्त होता है, जैसा कि यह' exec' के साथ करता है, लेकिन 'exec (cmd)' फ़ंक्शन के भीतर काम करता है, 'eval (compile (...)) ' नहीं करता। –

+0

इसके अलावा, यदि आप 'प्रिंट' में 'x' के बजाय' eval ("x") डालते हैं तो foo: x = ', x' यह भी काम करता है। दोनों में समान व्यवहार, पायथन 2.7 और पायथन 3.4 –

उत्तर

4

अपने कार्य में, निष्पादन काम करता है लेकिन xlocals() में समाप्त होता है, और फिर print बयान की कोशिश करता globals() में खोजने के लिए और NameError बढ़ाता है।

fn = '/tmp/tmp' 
mode = 'single' 

def foo(cmd, fn, mode): 
    eval(compile(cmd, fn, mode)) 
    print 'locals:', locals() 
    print 'foo: cmd=', cmd 
    print 'foo: x=', locals()['x'] 

cmd = "x = 1" 
eval(compile(cmd, fn, mode)) 
print 'global scope: cmd=', cmd 
print 'global scope: x=', x 

del(x) 
foo('x = 9', fn, mode) 

आउटपुट:

global scope: cmd= x = 1 
global scope: x= 1 
locals: {'x': 9, 'cmd': 'x = 9', 'mode': 'single', 'fn': '/tmp/tmp'} 
foo: cmd= x = 9 
foo: x= 9 
+1

बस ध्यान दिया कि 'exec' के साथ,' x' वास्तव में 'ग्लोबल्स' और 'स्थानीय' दोनों में समाप्त होता है; पहले मैंने सोचा कि दोनों समान 'ग्लोबल्स' और 'लोकल' उत्पन्न करेंगे। लेकिन, हाँ, यह 'स्थानीय लोगों' में क्यों नहीं दिखता है, और 'eval (" x ")' work क्यों काम करता है, जहां 'x' विफल रहता है? –

+2

मुझे लगता है कि किसी फ़ंक्शन में चर के दायरे को परिभाषा समय पर निर्धारित किया जाता है। इस प्रकार चीजें 'ए = "ए"; def print_a(): प्रिंट (ए); एक = "सी" 'एक unboundLocalError फेंक देगा। 'eval (" x ")' "एक नया पूर्ण लुकअप बनाता है" और इस प्रकार स्थानीय दायरे में देख सकते हैं। – syntonym

+0

@ सिंटोनिम यह एक दिलचस्प सिद्धांत है जो कुछ उदाहरण देता है, आपका उदाहरण दिया जाता है, और व्यवहार की व्याख्या करेगा। क्या आप इसके लिए एक संदर्भ प्रदान कर सकते हैं? –

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