首頁>技術>

最近在學習用 python3 寫測試用例,在匯入包和模組中踩到了坑。在網上找資料,發現不太全面,有些還有錯漏。於是決定自己總結,希望也能給遇到問題的小夥伴們帶來幫助。 注:使用python版本為3.7。

在任何語言中,依賴管理都是最基礎的。在 python 中也不例外。這裡我們要從模組和包說起。

模組和包模組 .py 為字尾的檔案視為一個模組。模組可以在其他 python 檔案中被匯入和使用。包 包含多個模組的資料夾,匯入該包即匯入該包內的模組。必須有 __init__.py檔案。__init__.py 檔案:匯入某個包時,會首先執行__init__.py 檔案,因此可以在裡面先行匯入需要用到的模組或者模組內的定義、方法。python 如何找到匯入的模組

python會按順序來查詢匯入的模組:從sys.modules 查詢 -> 查詢器查詢。

sys.modules:快取了之前匯入的所有模組。查詢器:預設有3個,按照內建模組(python官方模組等)-> 凍結模組-> import path(來自 sys.path,包括當前模組所在目錄,以及自行加入的目錄等)的路徑查詢。如何匯入模組匯入語法import xxx:直接匯入,xxx 為包/模組。from xxx import yyy:從 xxx 中匯入 yyy。xxx 為包/模組,yyy 可以為子包、模組、模組內的內容(類、方法)等。這種方式結合__init__.py,可以讓包和模組匯入更簡單,便於管理。匯入方式相對路徑 使用 . 或者 .. 的方式來包含指定匯入模組。. 代表當前包所在目錄,.. 為上級目錄。只能使用 from xxx import xxx 的方式匯入。因為 .moduleY 不是一個有效表示式。絕對路徑 使用 xxx.yyy.zzz 匯入。以當前包目錄為頂層目錄。例項說明專案結構 my_project 為專案資料夾,下圖為 my_project 的結構:my_project:包含 module_one 模組,package_a、package_b 子包。package_a:包含 a_module_one、a_module_two 模組,a_inner_package 子包。package_b:包含 b_module_one 模組。

每個模組中都會有一個方法,列印 “i am xxx_method”,來明確顯示我們的模組匯入和呼叫是成功的。

使用 import xxx 方式示例一 在 a_module_one.py 中引入上級、同級、下級包中模組。
# my_project/package_a/a_module_one.py import syssys.path.append("..")import module_one # 引入上級包中的模組import a_module_two # 引入同級包中的模組import a_inner_package.a_inner_module # 引入下級包中的模組module_one.module_one_method() # 結果:i am module_one_methoda_module_two.a_module_two_method() # 結果:i am a_module_two_methoda_inner_package.a_inner_module.a_inner_package_method() # 結果:i am a_inner_package_method

注意,引入上級包中模組需要將 .. 加入 sys.path 中,否則會找不到,因為python僅會從當前包的目錄開始查詢。

使用 from xxx import yyy 方式示例二:在包的__init__.py 中 import 僅需要的包內含有的子包和模組
# my_project/package_a/__init__.pyfrom .a_module_two import a_module_two_method # 匯入當前包的模組的方法from package_a.a_inner_package import a_inner_module # 匯入子包中的模組
示例三:在模組中引用包,使用其模組和方法
# my_project/module_one.py# 引入 my_project/package_a 包from package_a import a_inner_modulefrom package_a import a_module_two_methoda_module_two_method() # 結果:i am a_module_two_methoda_inner_module.a_inner_package_method() # 結果:i am a_inner_package_method
總結和注意事項推薦使用包對模組進行管理。推薦使用 from xxx imoprt yyy 的方式來引入。結合__init__.py檔案,引入包時,可以控制引入粒度,不需要引入無用的子包和模組。from xxx import yyy 方式說明 若在包 package_a 的 __init__.py 檔案中引入了其下具體的類、函式,則在引用 pakcage_a 的包中可以直接引用;若沒有,則 xxx 的粒度為包,yyy 必須為子包或直接模組。即yyy必須是能在下能直接找到的。例如:from package_a imoprt a_module_method 是錯誤的。(可參考示例三)踩坑記錄坑一現象:執行 my_project/package_a/__init__.py 檔案(檔案內容參考示例二)報錯: ModuleNotFoundError: No module named 'main.a_module_two'; 'main' is not a package原因:當前模組為 __init__.py。在當前模組執行時,.代表的是__name__變數;在被其他模組匯入和執行時,. 表示原模組的檔名。因此在用 . 相對路徑引入的時候,直接執行會報錯。坑二引用上級包中的模組,例如:from .. import module_xx。報錯:ValueError: attempted relative import beyond top-level package原因:當前所在包目錄為頂層目錄,python 會從該目錄開始查詢被引入的包和模組,因此它無法識別當前層級以上的包和模組。需要引入,要用sys.path.append加入路徑。參考文件python3.7官方文件:https://docs.python.org/zh-cn/3.7/reference/import.html#packages

12
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 2021技術趨勢報告,Python最受歡迎、低程式碼是重要趨勢