爲什麼python在函數中修改"字典型全局變量"不需要global

轉自http://blog.csdn.net/handsomekang/article/details/41392417?utm_source=tuicool

比如下面這段代碼

[python] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. s = 'foo'  
  2. d = {'a':1}  
  3. def f():  
  4.     s = 'bar'  
  5.     d['b'] = 2  
  6. f()  
  7. print s  
  8. print d  

爲什麼修改字典d的值不用global關鍵字先聲明呢?

這是因爲,

  • 在s = 'bar'這句中,它是“有歧義的“,因爲它既可以是表示引用全局變量s,也可以是創建一個新的局部變量,所以在python中,默認它的行爲是創建局部變量,除非顯式聲明global.
  • 在d['b']=2這句中,它是“明確的”,因爲如果把d當作是局部變量的話,它會報KeyError,所以它只能是引用全局的d,故不需要多此一舉顯式聲明global。

上面這兩句賦值語句其實是不同的行爲,一個是rebinding, 一個是mutation.


但是如果是下面這樣

[python] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. d = {'a':1}  
  2. def f():  
  3.     d = {}  
  4.     d['b'] = 2  
  5. f()  
  6. print d  

在d = {}這句,它是”有歧義的“了,所以它是創建了局部變量d,而不是引用全局變量d,所以d['b']=2也是操作的局部變量。


推而遠之,這一切現象的本質就是”它是否是明確的“

仔細想想,就會發現不止dict不需要global,所有”明確的“東西都不需要global。因爲int類型str類型之類的,只有一種修改方法,即x = y, 恰好這種修改方法同時也是創建變量的方法,所以產生了歧義,不知道是要修改還是創建。而dict/list/對象等,可以通過dict['x']=y或list.append()之類的來修改,跟創建變量不衝突,不產生歧義,所以都不用顯式global。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章