python 模塊加載


python 模塊加載

本文主要介紹python模塊加載的過程。

module的組成

所有的module都是由對象和對象之間的關系組成。

type和object

python中所有的東西都是對象,分為三類:類型type、類class和實例instance。

三種對象之間的兩種關系:

  • is kind of,基類和子類的關系
  • is instance of,類和對象的關系

類和對象的關系可以通過內建方法type來辨別。

python中,任何一個類都是直接或間接繼承自object,而每一個對象都會擁有自己的type類型,可以通過__class__屬性獲得。

運行環境初始化

python首先需要加載多個基礎的module,例如__builtin__,sys等,同時也會完成python類型系統的初始化和異常系統的初始化。

系統module初始化

Python內部維護了一個維護加載到內存的module集合,需要現在集合中查找module是否存在。如果存在直接返回該module對象,否則創建該module對象,並插入到module集合中。創建module后,需要設置module的屬性。

由於python的module集合是一個PyDictObject對象,而PyDictObject對象在Python中是一個可變對象,所以其中維護的元素有可能在運行時被刪除。對於Python的擴展module,例如sys,為了避免再一次初始化同樣的module,python將所有的擴展module通過一個全局的PyDictObject對象來進行備份維護。

啟動虛擬機

python包括兩種運行方式:命令行和腳本文件。

python中的run_mode函數基於AST抽象語法樹 (AST, Abstract Syntax Tree)完成了字節碼的編譯工作,並創建PyCodeObject對象。

python中所有的線程都是共享同樣的builtin名字空間。

模塊的動態加載

import功能包括:

  • python運行時的全局module緩存的維護和搜索;
  • 解析和搜索module路徑的樹形結構;
  • 對不同文件格式的module動態加載機制。

py文件中的import不會影響上一層的命名空間,只會影響各自的命名空間,也就是影響各自module自身維護的那個dict對象。但所有的import操作都會影響全局的module集合,這樣的話只要再一次import該module,python虛擬機只需要將全局module集合中緩存的對象返回。

在module的基礎之上,python提供了package機制(邏輯相關聯的module需要聚合到同一package中)。也就是說通過package機制來管理module,通過module來管理class。

文件件中存在__init__.py文件才能成為package(多個py文件組成的文件夾)。

在加載package下的module時,例如a.b.c,python內部將這個module視為一個樹形結構,c是b的子節點,b是a的子節點。python虛擬機在動態加載時,需要將這個樹形結構分解,然后從左到右依次去sys.modules中查找每一個符號是否存在。如果已經存在,假設存在a,那么在a對應的PyModuleObject對象中保持着__path__路徑信息,此時就可以在a.__path__路徑中搜索b和c了。

del刪除模塊只是把模塊從當前命名空間中刪除,但該module依然存在於module緩存中。

module緩存

python中的全局module集合sys.modules被稱為modules緩存,保證了module的唯一性,每當有import操作都會在該sys.modules查找,如果不存在就會將該module加入到sys.modules中。

如果已經加載的模塊發生改變,那么需要調用reload函數來重新加載該模塊。需要注意reload函數並不會重新創建該對象,而在在原有對象的基礎上做修改。


免責聲明!

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



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