[英]python dictionary comprehension in exec uses globals instead of locals
我發現在exec和eval中使用字典理解和其他方法之間存在以下差異。 總之,不同之處在於,當使用理解時,變量取自globals參數,但不使用理解的等效代碼從locals參數中獲取變量。
這可以從Python Software Foundation Windows安裝程序的Python 2.7.3中找到。
執行以下代碼時:
locals1 = {"d":{1: 'x', 2: 'y', 3: 'z'}, "test":3}
globals1 = dict(globals().items() + [("d", {1: 'a', 2: 'b', 3: 'c'}), ("test", 2)])
exec "new = {key:d[key] for key in d if key != test}" in globals1, locals1
print locals1
輸出是:
{'test': 3, 'new': {1: 'a', 3: 'c'}, 'd': {1: 'x', 2: 'y', 3: 'z'}}
請注意,字典(d)和測試值(測試)都取自globals參數。
執行等效代碼時:
locals2 = {"d":{1: 'x', 2: 'y', 3: 'z'}, "test":3}
globals2 = dict(globals().items() + [("d", {1: 'a', 2: 'b', 3: 'c'}), ("test", 2)])
exec "new = d.copy(); new.pop(test)" in globals2, locals2
print locals2
生成此輸出:
{'test': 3, 'new': {1: 'x', 2: 'y'}, 'd': {1: 'x', 2: 'y', 3: 'z'}}
在這種情況下,字典(d)和測試值(測試)都取自locals參數。
進一步的指示是,如果字典和/或測試值不在globals參數中,即使它們在locals參數中,具有理解的代碼的執行將失敗,並且變量未找到異常。
請注意,這不是關於使用exec的問題,我有充分的理由使用exec。 使用eval可以證明相同的情況。
這是完全正確的; 字典理解作為函數范圍執行。 在該范圍沒有定義的功能范圍引用的任何變量被推定為全局變量。
如果要在exec
-ed代碼中使用顯式函數,則會獲得相同的效果:
>>> locals3 = {"d":{1: 'x', 2: 'y', 3: 'z'}, "test":3}
>>> globals3 = dict(globals().items() + [("d", {1: 'a', 2: 'b', 3: 'c'}), ("test", 2)])
>>> exec "def f():\n new = d.copy()\n new.pop(test)\n return new\nnew = f()" in globals3, locals3
>>> print locals3
{'test': 3, 'new': {1: 'a', 3: 'c'}, 'd': {1: 'x', 2: 'y', 3: 'z'}, 'f': <function f at 0x106bbcaa0>}
請注意,理解是在單獨的范圍內執行的,因此在目標列表中分配的名稱不會在封閉范圍內“泄漏”。
在Python 2.x中, 列表推導沒有自己的范圍,這在Python 3中已經被改變了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.