歡迎關注博主 Mindtechnist 或加入【Linux C/C++/Python社區】一起探討和分享Linux C/C++/Python/Shell編程、機器人技術、機器學習、機器視覺、嵌入式AI相關領域的知識和技術。
Python中import模塊導入的實現原理
- 什么是模塊
- import搜索路徑
- import導入模塊的原理
- 圖書推薦
專欄:《python從入門到實戰》
什么是模塊
一個.py文件就是一個模塊,即Module。
模塊分為三種:python標準庫、第三方模塊、應用程序自定義模塊。
- import語句 – 導入模塊
- Directory – 文件夾(空的)
- Package – 比文件夾多了一個__init__.py
"""
file: cal.py
"""
def add(x, y)return x+y
def sub(x, y)return x-y
print(‘hello cal’)"""
file: test.py
"""
import cal
print(cal.add(1, 2))
import做了什么?
import導入模塊的時候,首先會把導入的文件執行一遍,比如說我們運行test.py的時候,print(‘hello cal’)也會被執行,因為import cal的時候就把cal.py運行了一遍。所以,我們在模塊文件中只寫功能(也就是函數),而不要寫可執行的語句。
- 執行被引入的py文件,即使只引入一個變量(from cal import add
),也會運行整個文件。 - 引入變量名 → 文件名變量
引入多個模塊
import cal, time
只引入一個方法
# 只引入一個方法
from cal import add
print(add(1, 2)) #可以直接使用add,不用加cal.
引入所有方法,不推薦使用,你并不知道都引入了哪些變量,可能會出現本文件變量與引入變量名字重復的情況。
#引入所有方法 – 不推薦使用,你并不知道都引入了哪些變量,可能會出現本文件變量與引入變量名字重復的情況。
from cal import *
#新的變量名會覆蓋舊的變量名
#+++++++++++++++++++++++++++
from cal import *
def add(x, y)return x+y+100
print(add(1, 2))
#+++++++++++++++++++++++++++
def add(x, y)return x+y+100from cal import *
print(add(1, 2))
#+++++++++++++++++++++++++++
import搜索路徑
import sys
print(sys.path) #查看路徑
path中包含python自己定義的路徑,以及當前執行的py文件的路徑,也就是說當前執行路徑會被自動加入到sys.path中,import就是按照這些路徑去搜索被引入的變量的。
也可以通過手動添加路徑
from path import cal
#path就是cal所在的路徑
import導入模塊的原理
首先import會根據路徑找到文件,根據路徑找到模塊后把模塊加載到內存中執行一遍,執行的時候是把模塊的內容拷貝到當前文件執行。import導入是將模塊從磁盤中把磁盤文件導入到內存中,這個速度是比較慢的,實際上,在導入時會有一個導入緩存,同一個模塊在導入第一次的時候會有一個緩存,以后再導入都是用的緩存的導入,所以有時候你可能遇到這樣的問題,被導入的文件已經刪除了,但是程序還是能運行,這是因為程序使用的是緩存的導入模塊。
from path import mode,它相當于把路徑進行了一次拼接path\mode.py,這是from的工作。
路徑拼接是在當前執行文件的路徑基礎上進行拼接。
當引入了很多模塊的時候,一個目錄下會有很多py文件,一般把bin.py作為要執行的文件,也就是整個程序的入口。而邏輯主文件叫做main.py,這里面包含了程序的主要邏輯,其他功能都放到其它文件中作為一個模塊。我們在運行的時候,運行bin.py,由bin.py去調用main.py中的主邏輯。也就是說只有bin是可執行的,其余文件都不應作為執行文件。
前面說過,sys.path中只會加入當前運行程序所在的路徑,bin.py是整個程序的運行文件,也就是說sys.path中只會加入bin.py的路徑,假如說文件有如下導入關系
假如說main.py和cal.py在同一級目錄,那么不用加路徑即可導入,但是如果bin.py和這兩個文件不在同一級目錄(比如在上一級目錄),那么bin.py導入main.py的時候就要加上main.py的路徑,但是這樣在執行的時候會報錯,因為bin.py間接導入了cal.py,并且bin.py只加了main.py的路徑而沒有加cal.py的路徑,前面說過sys.py只會包含當前運行路徑,也就是bin.py的路徑。
解決方法有兩個:
- 在main.py中加上cal.py的路徑from path import cal;
- 把路徑加到sys.path中;
file 獲取當前文件名
os.path.dirname(__file__) #獲取當前文件路徑
os.path.dirname(os.path.dirname(__file__)) #獲取當前文件的上一級路徑
pycharm會自己根據當前文件名獲取絕對路徑,并把絕對路徑通過os.path.dirname()返回給我們os.path.dirname(file),但是在終端運行的時候,終端并沒有這個功能,我們需要自己去找到絕對路徑,然后根據絕對路徑找到文件名,并反推出上一級目錄。
p = os.path.dirname(__file__) #獲取當前文件的絕對路徑
BASEDIR = os.path.dirname(os.path.dirname(p))
sys.psth.append(BASEDIR)
實際上,這三步的操作相當于把當前運行文件的上一級目錄通過相對路徑的方式添加到了環境變量。如果我們以絕對路徑的方式添加環境變量,當我們換了電腦或者環境,環境變量就失效了。我們這樣通過程序找出相對路徑來添加到環境變量,只要將當前整個工程一塊拷貝到別的機器,就一定可以找到這個環境變量。
圖書推薦
🔥強化學習:原理與Python實戰
強化學習利用獎勵信號訓練智能體。有些任務并沒有自帶能給出獎勵信號的環境,也沒有現成的生成獎勵信號的方法。為此,可以搭建獎勵模型來提供獎勵信號。在搭建獎勵模型時,可以用數據驅動的機器學習方法來訓練獎勵模型,并且由人類提供數據。我們把這樣的利用人類提供的反饋數據來訓練獎勵模型以用于強化學習的系統稱為人類反饋強化學習,示意圖如下。
想要學好這些知識,一定要有好的工具書,下面推薦一本理論與實踐結合的好書。書名:《強化學習:原理與Python實戰》
作者:肖智清
出版社:機械工業出版社
購買鏈接:點擊購買