मैं निष्पादन का उपयोग कर पाइथन कोड का एक टुकड़ा चलाने की कोशिश कर रहा हूं।पाइथन निष्पादन में ग्लोबल्स और स्थानीय()
my_code = """
class A(object):
pass
print 'locals: %s' % locals()
print 'A: %s' % A
class B(object):
a_ref = A
"""
global_env = {}
local_env = {}
my_code_AST = compile(my_code, "My Code", "exec")
exec(my_code_AST, global_env, local_env)
print local_env
जो निम्नलिखित उत्पादन में परिणाम है
locals: {'A': <class 'A'>}
A: <class 'A'>
Traceback (most recent call last):
File "python_test.py", line 16, in <module>
exec(my_code_AST, global_env, local_env)
File "My Code", line 8, in <module>
File "My Code", line 9, in B
NameError: name 'A' is not defined
हालांकि, अगर मैं इस के लिए कोड बदलने - यह ठीक काम करता है
my_code = """
class A(object):
pass
print 'locals: %s' % locals()
print 'A: %s' % A
class B(A):
pass
"""
global_env = {}
local_env = {}
my_code_AST = compile(my_code, "My Code", "exec")
exec(my_code_AST, global_env, local_env)
print local_env
तो - देने निम्न उत्पादन -
locals: {'A': <class 'A'>}
A: <class 'A'>
{'A': <class 'A'>, 'B': <class 'B'>}
स्पष्ट रूप से ए प्री ent और सुलभ - कोड के पहले भाग में क्या गलत हो रहा है?
my_code = """
class A(object):
pass
print 'locals: %s' % locals()
print 'A: %s' % A
class B(object):
print locals()
a_ref = A
"""
global_env = {}
local_env = {}
my_code_AST = compile(my_code, "My Code", "exec")
exec(my_code_AST, global_env, local_env)
print local_env
तो यह हो जाता है - मैं 2.6.5, चियर्स,
कॉलिन
* अद्यतन 1 *
अगर मैं() स्थानीय लोगों की जांच वर्ग के अंदर उपयोग कर रहा हूँ स्पष्ट करें कि स्थानीय स्थान() दोनों स्थानों पर समान नहीं है -
locals: {'A': <class 'A'>}
A: <class 'A'>
{'__module__': '__builtin__'}
Traceback (most recent call last):
File "python_test.py", line 16, in <module>
exec(my_code_AST, global_env, local_env)
File "My Code", line 8, in <module>
File "My Code", line 10, in B
NameError: name 'A' is not defined
हालांकि, अगर मैं ऐसा करते हैं, वहाँ कोई समस्या नहीं है -
def f():
class A(object):
pass
class B(object):
a_ref = A
f()
print 'Finished OK'
* अद्यतन 2 *
ठीक है, इसलिए यहाँ डॉक्स - http://docs.python.org/reference/executionmodel.html
'एक वर्ग परिभाषा एक निष्पादन योग्य है बयान जो नामों का उपयोग और परिभाषित कर सकता है। ये संदर्भ नाम समाधान के लिए सामान्य नियमों का पालन करते हैं। कक्षा परिभाषा का नामस्थान कक्षा का गुण शब्दकोश बन जाता है। कक्षा के दायरे में परिभाषित नाम विधियों में दिखाई नहीं दे रहे हैं। '
ऐसा लगता है कि 'ए' निष्पादन योग्य कथन के भीतर एक मुक्त चर के रूप में उपलब्ध कराया जाना चाहिए जो कि बी की परिभाषा है, और यह तब होता है जब हम ऊपर f() कहते हैं, लेकिन जब हम निष्पादन का उपयोग नहीं करते हैं ()।
my_code = """
class A(object):
pass
print 'locals in body: %s' % locals()
print 'A: %s' % A
def f():
print 'A in f: %s' % A
f()
class B(object):
a_ref = A
"""
जो आउटपुट
locals in body: {'A': <class 'A'>}
A: <class 'A'>
Traceback (most recent call last):
File "python_test.py", line 20, in <module>
exec(my_code_AST, global_env, local_env)
File "My Code", line 11, in <module>
File "My Code", line 9, in f
NameError: global name 'A' is not defined
तो मुझे लगता है कि नए सवाल यह है कि - - क्यों उन स्थानीय लोगों कार्यों और वर्ग परिभाषा में नि: शुल्क चर के रूप में दिखाया जा रहा है नहीं कर रहे हैं यह निम्नलिखित के साथ और अधिक आसानी से दिखाया जा सकता है - यह एक सुंदर मानक बंद परिदृश्य की तरह लगता है।
अच्छा लगा। कभी नहीं देखा। – zefciu
यह इस प्रश्न में के रूप में ही मुद्दा हो रहा है: http://stackoverflow.com/questions/2749655/why-are-closures-broken-within-exec सूचक के लिए – interjay
धन्यवाद - मैं एक अजगर गुरु नहीं हूँ, लेकिन ऐसा प्रतीत होता है कि जब मैं स्थानीय() को मुद्रित करता हूं, ए * को * स्थानीय चर में संकलित किया गया है - यानी यह जानता है कि इसके साथ क्या करना है। सवाल आप पर प्रकाश डाला में जवाब कहते हैं - 'के लिए संकलन पता चला है कि एक एक freevar है कोई तरीका नहीं है, तो यह एक वैश्विक संदर्भ के लिए यह संकलित' समस्या यहां है कि स्थानीय लोगों() के अंदर नए सिरे से परिभाषित लगता है निष्पादन का उपयोग करते समय बी का शरीर, लेकिन फ़ंक्शन का उपयोग करते समय नहीं (प्रश्न में अद्यतन देखें)? आसानी से है कि इसका जवाब यद्यपि के निहितार्थ की मेरी गलतफहमी हो सकता है ... – hawkett