91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

如何理解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

谷城县| 石景山区| 家居| 若尔盖县| 花莲县| 马尔康县| 平远县| 辰溪县| 静乐县| 深水埗区| 衡南县| 锡林郭勒盟| 福清市| 富民县| 丹阳市| 宜都市| 江华| 利辛县| 巴塘县| 泾川县| 锦州市| 扎鲁特旗| 山东省| 南昌县| 弋阳县| 竹山县| 阳信县| 大埔县| 湖州市| 江都市| 和龙市| 全椒县| 杂多县| 简阳市| 许昌市| 邢台县| 洛川县| 涡阳县| 中卫市| 福州市| 湾仔区|