日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python3导入模块原理_Python模块导入机制与规范

發(fā)布時間:2023/12/10 python 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python3导入模块原理_Python模块导入机制与规范 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

在我們平常工程里使用Python的過程中,經(jīng)常需要解決各個模塊的導(dǎo)入問題,而且也常常遇到引用路徑查找不到、交叉導(dǎo)入模塊等等問題,故寫這篇文章,旨在講述Python的模塊導(dǎo)入機制和我們平時大型項目中應(yīng)該遵循的模塊導(dǎo)入規(guī)范

Python模塊導(dǎo)入

日常編程中,為了能夠復(fù)用寫過的代碼邏輯,我們都會把這些代碼封裝成為模塊,需要用到的時候可以直接導(dǎo)入復(fù)用,以便提高我們的開發(fā)效率。 module能定義函數(shù)、類、變量,也能包含可執(zhí)行的代碼。module來源有3種: ①Python內(nèi)置的模塊(標(biāo)準庫); ②第三方模塊; ③自定義模塊;

導(dǎo)入原理

模塊的導(dǎo)入一般是在文件頭使用import關(guān)鍵字,import一個模塊相當(dāng)于先執(zhí)行了一次這個被導(dǎo)入模塊,然后在本命名空間建立一個與被導(dǎo)入模塊命名空間的聯(lián)系,相當(dāng)于在本命名空間新建了一個變量,這個變量名稱是被導(dǎo)入模塊的名稱,指向被導(dǎo)入模塊的命名空間。所以導(dǎo)入的這個模塊相當(dāng)于一個變量,因此多次導(dǎo)入同一個模塊只有第一次導(dǎo)入的時候會被執(zhí)行(后續(xù)導(dǎo)入會判斷到這個模塊變量已存在所以不執(zhí)行)

路徑查找機制

每一個導(dǎo)入的模塊都會在Python內(nèi)置字典sys.modules中,Python一啟動,它將被加載在內(nèi)存中,當(dāng)我們導(dǎo)入新modules,sys.modules將自動記錄下該module。 Python的模塊查找路徑的機制是: 1. 查找sys.path中的所有路徑下是否有該模塊,有則開辟新空間加載該模塊; 2. 查看sys.modules中是否有內(nèi)置包或已安裝的第三方包,有則開辟新空間加載該模塊;

所以對于我們自己編寫的模塊,如果封裝并發(fā)布到了PyPi,則可以用pip install直接安裝,并在啟動時加載在內(nèi)存中,通過sys.modules可以查看到 而對于僅需要在本項目中復(fù)用的模塊,我們在復(fù)用代碼中將其路徑加入到sys.path中,同樣可以引用到該模塊。

絕對路徑導(dǎo)入

所有的模塊import都從“根節(jié)點”開始。根節(jié)點的位置由sys.path中的路徑?jīng)Q定,項目的根目錄一般自動在sys.path中。如果希望程序能處處執(zhí)行,需手動修改sys.path

import sys,os

BASE_DIR = os.path.dirname(os.path.abspath(__file__))#項目根目錄所在的絕對路徑

sys.path.append(BASE_DIR)

import A, B #導(dǎo)入A、B包

相對路徑導(dǎo)入

只關(guān)心相對自己當(dāng)前目錄的模塊位置就好。不能在包(package)的內(nèi)部直接執(zhí)行(會報錯)。不管根節(jié)點在哪兒,包內(nèi)的模塊相對位置都是正確的。

#from . import b2 #這種導(dǎo)入方式會報錯,只有在包內(nèi)部直接執(zhí)行的時候才可以這樣導(dǎo)入。

import b2#正確

b2.print_b2()

Python模塊導(dǎo)入常見問題單獨import某個包名稱時,不會導(dǎo)入該包中所包含的所有子模塊 解決辦法:導(dǎo)入的包中也包含了其他包的導(dǎo)入,此時需要在每個包的init.py文件中導(dǎo)入該包下的所有模塊,最上層才可以直接引用最下層的包的類和方法

init文件

當(dāng)一個文件夾下有init.py時,意為該文件夾是一個包(package),其下的多個模塊(module)構(gòu)成一個整體,而這些模塊(module)都可通過同一個包(package)導(dǎo)入其他代碼中。 其中init.py文件 用于組織包(package),方便管理各個模塊之間的引用、控制著包的導(dǎo)入行為。

該文件可以什么內(nèi)容都不寫,即為空文件(為空時,僅僅用import [該包]形式 是什么也做不了的),存在即可,相當(dāng)于一個標(biāo)記。

在python3中,即使包下沒有__init__.py文件,import 包仍然不會報錯,而在python2中,包下一定要有該文件,否則import 包會報錯

all變量

all 是一個重要的變量,用來指定此包(package)被import *時,哪些模塊(module)會被import進【當(dāng)前作用域中】。不在all列表中的模塊不會被其他程序引用。可以重寫all,如 all= [‘當(dāng)前所屬包模塊1名字’, ‘模塊1名字’],如果寫了這個,則會按列表中的模塊名進行導(dǎo)入

name變量

在包內(nèi)部直接運行時,包的name == 'main',但是在外部導(dǎo)入包是,可以通過

if __name__ == '__main__':

來避免實現(xiàn)包內(nèi)部調(diào)試時的邏輯

循環(huán)導(dǎo)入

當(dāng)兩個模塊A和B之間相互import時,就會出現(xiàn)循環(huán)導(dǎo)入的問題,此時程序運行會報錯:can not import name xxx,如:

# a.py

print('from a.py')

from b import x

y = 'a'

# b.py

print('from b.py')

from a import y

x = 'b'

我們來分析一下這種錯誤是怎么出現(xiàn)的: 1. 在sys.modules中查找 符號“module b”; 2. 如果符號“module b”存在,則獲得符號“module b”對應(yīng)的module對象; 從的dict中獲得 符號“x”對應(yīng)的對象。如果“x”不存在,則拋出異常“ImportError: cannot import name ‘x’” 3. 如果符號“module b”不存在,則創(chuàng)建一個新的 module對象。不過此時該新module對象的dict為空。然后執(zhí)行module b.py文件中的語句,填充的dict。

因此在a.py中執(zhí)行from b import x的順序就是1->3,先引入b,b里面from a import y由相當(dāng)于執(zhí)行了a.py,順序是1->2,因為此時b已經(jīng)引入所以不會執(zhí)行3,2中無法找到x對象,因為引入b時還沒執(zhí)行到x='b'這一步,所以報錯了

解決辦法延遲導(dǎo)入,把import語句寫在方法/函數(shù)里,將它的作用域限制在局部;

頂層先引入模塊,再把from x import y改成import x.y形式;

其實出現(xiàn)循環(huán)引用問題的根本原因是程序設(shè)計不合理,每個包都應(yīng)該由上層使用的模塊去導(dǎo)入,而不應(yīng)該在包與包之間各種相互導(dǎo)入,所以應(yīng)該更改代碼布局,可合并或分離競爭資源;

大型項目中Python模塊導(dǎo)入規(guī)范分離模塊,將同一類別的模塊放在同一目錄下,形成類別分明的目錄架構(gòu),如:

每一個模塊目錄都要寫init.py文件,可以同時定義all限定可導(dǎo)入的范圍;

源碼根目錄可以定義BASE_DIR,限定好根目錄路徑,啟動py文件可以用絕對路徑導(dǎo)入各個模塊,將必要模塊都加入到sys.path中;

各個服務(wù)之間(例如model需要引入common的模塊方法),可以通過相對路徑引用模塊;

程序設(shè)計時避免循環(huán)導(dǎo)入,可由調(diào)用者(服務(wù)文件)作為上層第三方引入需要的各個模塊,這樣就可以減少各個模塊的相互導(dǎo)入。

參考文獻

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的python3导入模块原理_Python模块导入机制与规范的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。