Python模塊的動態加載機制


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']

不同點:

  1. import A.tank 在local名稱空間中引入符合"A",並且將其映射到module A
  2. 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的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM