python 模塊==命名空間?

起因: 想利用模塊傳遞某個變量,修改某個變量的值,且在其它模塊中也可見
於是我做了這樣一個實驗:
[email protected]:vearne/test_scope.git

base.py

value = 10

b.py

import base
def hello():
    print 'scope base', base.value, id(base.value)

main.py

from base import value
from b import hello
print 'scope base', value, id(value)
value = 20
print 'scope local', value, id(value)
hello()

運行python main.py
輸出結果如下:

['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'hello', 'value']
scope base 10 140195531889072
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'hello', 'value']
scope local 20 140195531888832
scope base 10 140195531889072

大家可以看出,value 的值並沒有被修改,並且id值(對象的內存地址) 不一致,因此我們得出結論, value 和 base.value 存在在不同位置,是兩個不同的對象。
閱讀python官方文檔
https://docs.python.org/2/tutorial/modules.html
我找到這樣一段話

Each module has its own private symbol table, which is used as the global symbol table by all functions defined in the module. Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user’s global variables. On the other hand, if you know what you are doing you can touch a module’s global variables with the same notation used to refer to its functions, modname.itemname.

Modules can import other modules. It is customary but not required to place all import statements at the beginning of a module (or script, for that matter). The imported module names are placed in the importing module’s global symbol table.

每個模塊有一個自己的符號表,當我們引入一個模塊時,這個符號表中的內容就會被修改,使用dir() 可以查看當前模塊的符號表中的符號列表
看下面的列子:

print '------------------'
a = 15
print dir()
print '------------------'
import math
print dir()
print '------------------'
from datetime import timedelta
print dir()

運行結果如下:

------------------
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'a']
------------------
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'a', 'math']
------------------
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'a', 'math', 'timedelta']

最後回到前面的例子:

from base import value
value = 20  # 這裏我們並沒有修改模塊base中value的值,而是重新定義了一個本地變量, 並且符號表中的指向已經被修改了(指向一個本地變量value)
...

其實這麼看python的模塊還有點像命名空間,隔離同名變量,防止命名衝突

參考資料:
https://docs.python.org/2/library/datetime.html

發佈了91 篇原創文章 · 獲贊 20 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章