亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解Python模塊之間的相互引用問題

發布時間:2021-10-19 11:47:21 來源:億速云 閱讀:199 作者:iii 欄目:編程語言

這篇文章主要講解了“如何理解Python模塊之間的相互引用問題”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何理解Python模塊之間的相互引用問題”吧!

在某次運行過程中出現了如下兩個報錯:

報錯1: ModuleNotFoundError: No module named '__main__.src_test1'; '__main__' is not a package
報錯2: ImportError: attempted relative import with no known parent package

于是基于這兩個報錯探究了一下python3中的模塊相互引用的問題,下面來逐個解析,請耐心看完。

好的,我們先來構造第一個錯,測試代碼結構如下:

|--- test_main.py
|--- src
  |--- __init__.py                                                              
    |--- src_test1.py
    |--- src_test2.py

src_test2.py 代碼

class Test2(object):
    def foo(self):
        print('I am foo')

src_test1.py 代碼,引用Test2模塊

from .src_test2 import Test2

def fun1():
    t2 = Test2()
    t2.foo()
if __name__ == "__main__":
    fun1()

此時運行 src_test1.py 報錯“No module named '__main__.src_test1'; '__main__' is not a package”

問題原因:

主要在于引用src_test2模塊的時候,用的是相對路徑".",在import語法中翻譯成"./",也就是當前目錄下,按這樣理解也沒有問題,那為什么報錯呢?

從 PEP 328 中,我們找到了關于 the relative imports(相對引用)的介紹

如何理解Python模塊之間的相互引用問題

通俗一點意思就是,你程序入口運行的那個模塊,就默認為主模塊,他的name就是‘main’,然后會將本模塊import中的點(.)替換成‘__main__’,那么 .src_test2就變成了 __main__.src_test2,所以當然找不到這個模塊了。

解決方法:

因此,建議的做法是在 src同層級目錄創建 引用模塊 test_main.py(為什么不在src目錄下創建,待會下一個報錯再講),并引用src_test1模塊,代碼如下:

from src.src_test1 import fun1

if __name__ == "__main__":
    fun1()

那為什么這樣執行就可以了呢,其中原理是什么呢?我是這樣理解的(歡迎糾正):test_main執行時,他被當做根目錄,因此他引用的src.src_test1 是絕對路徑,這樣引用到哪都不會錯,此時他的name=‘main’,當執行src_test1的時候,注意了此時test1的name是 src.src_test1,那么在test1中使用的是相對路徑,查找邏輯是先找到父節點(src目錄),再找父節點下面的src_test2,因此可以成功找到,Bingo!

輔證:

構造一個例子,就可以理解上面的 執行目錄就是根目錄 的說法了,修改test1,使引用test_main:

from .. import test_main

報錯:ValueError: attempted relative import beyond top-level package

OK,那繼續構造第二個報錯:

上文中說過,解決main 的問題,就是創建一個模塊,來調用使用相對路徑的模塊,那么為什么我不能在相同目錄下創建這個文件來調用呢?讓我們來測試下代碼:

創建test_src.py文件,代碼結構變更如下:

|--- test_main.py
|--- src
  |--- __init__.py                                                              
    |--- src_test1.py
    |--- src_test2.pys
    |--- test_src.py

test_src 代碼:

from src_test1 import fun1

if __name__ == "__main__":
    fun1()

執行報錯:ImportError: attempted relative import with no known parent package

問題原因:

當執行test_src時,按上文理解,此時執行文件所在的目錄為根目錄,那么引用test1的時候,需要注意的是,此時test1的name屬性不再是src.src_test1,因為程序感知不到src的存在,此時他的絕對路徑是 src_test1,此時再次引用相對路徑查找的test2,同樣的步驟,需要先找到父節點,而此時他自己就是根節點了,已經沒有父節點了,因此報錯“no known parent package”。

解決方法:

此時為了避免父節點產生矛盾,因此將test1中的引入去掉相對引用即可

from .src_test2 import Test2    -->    from src_test2 import Test2
繼續深入:

那使用相對路徑和絕對路徑,編譯器是怎么找到這個模塊的呢?

執行import的時候,存在一個引入的順序,即優先查找執行目錄下有沒有此文件,如沒有,再查找lib庫下,如還沒有,再查找sys.path中的路徑,如再沒有,報錯。

所以不管是當前目錄,還是 sys.path中的目錄,都可以查到 src_test2這個模塊,就可以編譯成功。

號外

解決完上述問題后,不管我們用哪種方式,我們調試代碼時,都是單個文件調試,但此時根目錄就不對了,import方式又要改動,執行起來很麻煩,所以這里推薦另一種方式(有更好的方式歡迎留言),使用sys.path.append()的方法

import sys,os
sys.path.append(os.getcwd())
from src.src_test2 import Test2

使用append的方式,將程序文件根目錄放進了sys.path中,然后再引用絕對路徑,這樣的方式,不管使用上文中的第一或第二執行方式都可以調用,也可以單獨編譯test1文件,不用修改import路徑,也是相對安全的方式。但是缺點就是,如果你修改了某一個包名,需要將所有引用地方都修改一下,工作量大,所以因地制宜。

感謝各位的閱讀,以上就是“如何理解Python模塊之間的相互引用問題”的內容了,經過本文的學習后,相信大家對如何理解Python模塊之間的相互引用問題這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

芦溪县| 唐山市| 海丰县| 辽源市| 珠海市| 宜黄县| 南靖县| 乐东| 大荔县| 会宁县| 沿河| 隆回县| 赣榆县| 南宫市| 会昌县| 海兴县| 丹江口市| 潜山县| 江油市| 沙河市| 扬州市| 惠安县| 常德市| 昭通市| 比如县| 高台县| 绿春县| 云龙县| 布尔津县| 宣化县| 离岛区| 筠连县| 阳东县| 铁岭县| 温泉县| 论坛| 耒阳市| 大同县| 德保县| 宁波市| 清镇市|