2012-08-09 19 views
4

我無法找到這種行爲的充分解釋。Python - 當地人()和關閉

>>> def a(): 
...  foo = 0 
...  print locals() 
...  def b(): 
...   print locals() 
...  b() 

>>> a() 
{'foo': 0} 
{} 

但是:

>>> def a(): 
...  foo = 0 
...  print locals() 
...  def b(): 
      foo 
...   print locals() 
...  b() 

>>> a() 
{'foo': 0} 
{'foo': 0} 

據我所知,在第二種情況下有一個封閉的,但我無法找到的其實是什麼,在什麼條件下應該返回功能locals()的詳細描述。

+0

如果我是你,我會接受邁克爾舒勒的回答(他評論中的upvote/downvote下的複選標記)。分享愛心,併爲他的努力表示讚賞! – rsegal 2012-08-10 03:50:10

+0

@rsegal Rostyslav Dzinko的答案很重要。 – 2012-08-10 14:30:35

+0

真的!我應該說得更好一些:我試着說更多的是你應該對你的答案傾訴,而不是我最喜歡的。 但是我確實並且仍然認爲Michael的回答更直接地解決了你的問題,指出Python搜索範圍很大的模糊值,這就是你演示的行爲! – rsegal 2012-08-10 14:44:15

回答

3

locals()內置函數打印綁定到代碼對象的本地符號表,並在解釋器在源代碼中接收到名稱時填充。

第二示例中,在拆卸時,將包含在b功能碼LOAD_GLOBAL FOO字節代碼指令。此LOAD_GLOBAL指令將向上移動作用域,找到外部foo名稱,並通過將名稱偏移添加到閉包(函數b)代碼對象的屬性中,將其綁定到代碼對象。 ()函數打印本地符號表(如前所述,函數的代碼對象的co_names屬性)。

閱讀更多關於代碼對象here

5

如果您沒有在閉包中分配foo,則Python會將其解析爲上一級作用域的foo(並且直到它找到foo某處或引發異常)。

通過在第二個例子中b()foo,你把foo到當地人中b(),但它解析爲fooa()體內。如果分配,說,foo = 1b(),你會看到

{'foo': 0} 
{'foo': 1} 

作爲輸出。

+0

謝謝,但我需要更多的內部細節:( – 2012-08-10 14:58:24