我試圖運行一段使用exec的python代碼。全局和本地人在python exec()
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'>}
顯然A是pres ent和可訪問 - 第一段代碼出了什麼問題?我使用的是2.6.5,歡呼聲,
科林
*更新1 *
如果我入住的是當地人()裏面的類 -
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
然後就變成明確說當地人()在兩地都不一樣 -
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
「A類的定義是一個可執行可能使用和定義名稱的語句。這些引用遵循名稱解析的正常規則。類定義的名稱空間成爲該類的屬性字典。在類範圍中定義的名稱在方法中不可見。'
在我看來,'A'應該作爲B的定義的可執行語句中的一個自由變量提供,而這發生在我們調用上面的f()時,而不是當我們使用exec )。這可以更容易地顯示具有以下 -
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 2010-05-25 12:07:00
它似乎是在這個問題相同的問題:http://stackoverflow.com/questions/2749655/why-are-closures-broken-within-exec – interjay 2010-05-25 12:38:13
感謝指針 - 我不是一個蟒蛇大師,但是當我打印locals()時,似乎A *已經被編譯爲一個局部變量 - 也就是說它確實知道如何處理它。您突出顯示的問題中的答案是 - '編譯時無法知道a是自由變量,因此它將其編譯爲全局引用' 這裏的問題似乎是locals()在B使用exec時的主體,但不使用函數時(請參閱更新問題)?可能很容易成爲我對這個答案的含義的誤解,雖然... – hawkett 2010-05-25 12:55:26