Python在運行環境初始化中,就將sys module加載到了內存中,
實際上,Python是將一大批的module加載到了內存中。但是為了使local名字空間能夠達到最干凈的效果,Python並沒有將這些符號暴露在當前的local名字空間中,
而是需要用戶顯式的通過import機制通知Python:需要將這個符號引入到local名字空間中。這些預先被加載進內存的module存放在sys.modules中
可以看到os module是從C:\Python25\lib\os.pyc這個文件中引入的,它是一個內建的module。通過import機制,這個module被引入到了當前的local名字空間。從兩個不同id操作中可以看到,Python虛擬機的import動作引入的正是事先已經在Python初始化階段被加載到sys.modules集合中的os module。
嵌套import
在usermodule1.py和usermodule2.py中進行的import動作並沒有影響到上一層的名字空間,而只是影響到了各個module自身的名字空間,更准確的說是影響到了各個module自身所維護的那個dict對象。
實際上,所有的import動作都會影響到全局module集合,即如果程序的另一處再次import這個module,Python虛擬機只需要將全局module集合中緩存的那個module對象返回即可。
import A.tank
import之前的名稱空間: ['__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
import之后的名稱空間: ['A', '__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
A的local名稱空間 ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'tank']
from A import tank
import之前的名稱空間: ['__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
import之后的名稱空間: ['__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'tank']
import A.tank與from A import tank的區別:
相同點:
兩者都將A.tank module以及A作為moudle添加到sys.modules集合中
sys.modules['A']
sys.modules['A.tank']
不同點:
- import A.tank 在local名稱空間中引入符合"A",並且將其映射到module A
- from A import tank Python虛擬機在local名稱空間中引入符合"tank",並將其映射到module A.tank
符號重命名
之前的例子都是通將module自身的名字暴露到了當前的local名稱空間,Python通過as關鍵字可以控制module以什么名字引入到當前的local名稱空間中。
當前local名稱空間中的Tank實際被映射到了module A.tank。import A.tank 在名稱空間引入的是符號"A",而使用as后,引入的是"Tank",所以當前名稱空間中無法訪問到A了
符號的銷毀與重載
- 符號銷毀
只是刪除了符號"Tank",並沒有真正從sys.modules集合中刪除module
- reload操作
只是向對應的module中添加新的符號,如果有符號在源文件中被刪除,這種刪除是不會影響到module所維護的dict的。