2017-09-03 132 views
3

a comment:「全球在Python中基本上意味着在模塊級別」。然而,在一個名爲my_module.py文件運行此代碼:什麼是模塊變量與全局變量?

import my_module as m 

foo = 1 
m.bar = m.foo + 1 

if __name__ == "__main__": 
    print('foo:', foo) 
    print('m.foo:', m.foo) 
    print('m.bar:', m.bar, '\n') 

    for attrib in ('foo', 'bar'): 
     print("'{0}' in m.__dict__: {1}, '{0}' in globals(): {2}".format(
      attrib, 
      attrib in m.__dict__, 
      attrib in globals())) 

輸出:

foo: 1 
m.foo: 1 
m.bar: 2 

'foo' in m.__dict__: True, 'foo' in globals(): True 
'bar' in m.__dict__: True, 'bar' in globals(): False 

究竟是模塊和全局命名空間?

爲什麼在模塊命名空間中有__dict__屬性,但不在全局命名空間中?

爲什麼m.bar部分__dict__而不是globals()的一部分?

回答

3

基本上有3個不同的的範圍在Python:

  • 模塊範圍
  • 類/實例範圍(保存在類或實例__dict__屬性)(在模塊__dict__保存屬性)
  • 功能範圍

(也許我忘了的東西有...)

這些工作幾乎相同,除了類作用域可以動態使用__getattr____getattribute__來模擬實際上不存在的變量的存在。而函數是不同的,因爲你可以傳遞變量(使它們成爲其作用域的一部分)並從函數中返回它們。

然而,當你談論全球(和本地範圍)時,你必須從可見性的角度來考慮它。全球範圍內沒有(除了Pythons內置插件,例如intzip等),只有全局模塊範圍。這代表您可以在模塊中訪問的所有內容。

因此,在你的文件的開頭這個「大致」表示模塊範圍:

enter image description here

然後你import my_module as m這意味着m現在是my_module參考,該基準是在全球範圍內的當前文件。這意味着'm' in globals()將爲真。

enter image description here

也可以定義foo=1,使您的全球範圍的foo一部分,'foo' in globals()True。但是foom.foo完全不同!

enter image description here

那麼你就m.bar = m.foo + 1訪問全局變量m並且基於m小號屬性foo屬性bar。這不會使m s foobar成爲當前全球範圍的一部分。它們仍位於my_module的全球範圍內,但您可以通過全局變量m訪問my_module的全局範圍。

enter image description here

AB這裏縮寫模塊名稱,但我希望它仍然是可以理解的。

+0

很清楚,我的錯誤並不是要明白兩個foo是不同的實體,否則我也會挑戰其餘的。順便說一句,我現在也明白我也可以訪問'm.m.m.m.bar': – mins

+0

我有一個問題,但是:是否有一個實際的用例來導入模塊本身?還是隻是好奇? – MSeifert

+0

不是一個真實的案例。試圖比較'__dict__'和'globals()'的內容。我不能沒有進口。 – mins

-1

全局變量是您可以在任何給定時間使用變量的地方,即使在函數或for循環中也是如此。局部變量在函數中定義,但不返回。