国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 後端開發(fā) Python教學(xué) 在 Python 中修復(fù)循環(huán)導(dǎo)入的不同方法

在 Python 中修復(fù)循環(huán)導(dǎo)入的不同方法

Nov 05, 2024 am 02:21 AM

你在Python中遇過循環(huán)導(dǎo)入嗎?嗯,這是一種非常常見的程式碼味道,表示設(shè)計或結(jié)構(gòu)有問題。

循環(huán)導(dǎo)入範(fàn)例

循環(huán)導(dǎo)入是如何發(fā)生的? 當(dāng)兩個或多個相互依賴的模組在完全初始化之前嘗試導(dǎo)入時,通常會發(fā)生此導(dǎo)入錯誤。

假設(shè)我們有兩個模組:module_1.py 和 module_2.py。

# module_1.py
from module_2 import ModY
class ModX:
    mody_obj = ModY()
# module_2.py
from module_1 import ModX
class ModY:
    modx_obj = ModX()

在上面的程式碼片段中,module_1和module_2都是相互依賴的。

module_1 中 mody_obj 的初始化依賴 module_2,module_2 中 modx_obj 的初始化依賴 module_1。

這就是我們所說的循環(huán)依賴。兩個模組在嘗試互相載入時都會陷入導(dǎo)入循環(huán)。

如果我們執(zhí)行 module_1.py,我們將得到以下回溯。

Traceback (most recent call last):
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
  File "module_2.py", line 1, in <module>
    from module_1 import ModX
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)

這個錯誤說明了循環(huán)導(dǎo)入的情況。當(dāng)程式嘗試從 module_2 導(dǎo)入 ModY 時,當(dāng)時 module_2 尚未完全初始化(由於另一個導(dǎo)入語句嘗試從 module_1 導(dǎo)入 ModX)。

如何修正 Python 中的循環(huán)導(dǎo)入? 有多種方法可以消除 Python 中的循環(huán)導(dǎo)入。

修復(fù) Python 中的循環(huán)導(dǎo)入

將程式碼移至公用文件中

我們可以將程式碼移到一個公開檔案中以避免匯入錯誤,然後嘗試從該檔案匯入模組。

# main.py ----> common file
class ModX:
    pass

class ModY:
    pass

在上面的程式碼片段中,我們將類別 ModX 和 ModY 移到一個公用檔案 (main.py) 中。

# module_1.py
from main import ModY

class Mod_X:
    mody_obj = ModY()
# module_2.py
from main import ModX

class Mod_Y:
    modx_obj = ModX()

現(xiàn)在,module_1 和 module_2 從 main 導(dǎo)入類,修復(fù)了循環(huán)導(dǎo)入的情況。

這種方法有一個問題,有時程式碼庫太大,將程式碼移到另一個檔案中會存在風(fēng)險。

將導(dǎo)入移至模組末尾

我們可以將導(dǎo)入語句移到模組末尾。這將為導(dǎo)入另一個模組之前留出時間來完全初始化模組。

# module_1.py
class ModX:
   pass

from module_2 import ModY

class Mod_X:
   mody_obj = ModY()
# module_2.py
class ModY:
   pass

from module_1 import ModX

在類別/函數(shù)範(fàn)圍內(nèi)導(dǎo)入模組

在類別或函數(shù)作用域內(nèi)導(dǎo)入模組可以避免循環(huán)導(dǎo)入。這允許僅在調(diào)用類別或函數(shù)時導(dǎo)入模組。當(dāng)我們想要最小化記憶體使用時,它是相關(guān)的。

# module_1.py
class ModX:
  pass

class Mod_X:
   from module_2 import ModY
   mody_obj = ModY()
# module_2.py
class ModY:
   pass

class Mod_Y:
   from module_1 import ModX
   modx_obj = ModX()

我們分別將 import 語句移至 module_1 和 module_2 中的類別 Mod_X 和 Mod_Y 範(fàn)圍內(nèi)。

如果我們執(zhí)行 module_1 或 module_2,我們不會收到循環(huán)導(dǎo)入錯誤。但是,這種方法使得類別只能在類別的範(fàn)圍內(nèi)訪問,因此我們無法全域利用導(dǎo)入。

使用模組名稱/別名

使用模組名稱或僅像這樣的別名可以解決問題。這允許兩個模組透過將循環(huán)依賴推遲到運(yùn)行時來完全加載。

# module_1.py
from module_2 import ModY
class ModX:
    mody_obj = ModY()
# module_2.py
from module_1 import ModX
class ModY:
    modx_obj = ModX()

使用 importlib 庫

我們也可以使用 importlib 函式庫動態(tài)導(dǎo)入模組。

Traceback (most recent call last):
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
  File "module_2.py", line 1, in <module>
    from module_1 import ModX
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)
# main.py ----> common file
class ModX:
    pass

class ModY:
    pass

Python 套件中的循環(huán)導(dǎo)入

通常,循環(huán)導(dǎo)入 來自同一包內(nèi)的模組。在複雜的專案中,目錄結(jié)構(gòu)也很複雜,包內(nèi)包。

這些套件和子包包含 __init__.py 文件,以提供更輕鬆的模組存取。這就是有時無意中在模組之間產(chǎn)生循環(huán)依賴的地方。

我們有以下目錄結(jié)構(gòu)。

# module_1.py
from main import ModY

class Mod_X:
    mody_obj = ModY()

我們有一個 mainpkg 套件和一個 main.py 檔案。我們在 mainpkg 中有兩個子包 modpkg_x 和 modpkg_y。

這是 modpkg_x 和 modpkg_y 中每個 Python 檔的樣子。

mainpkg/modpkg_x/__init__.py

# module_2.py
from main import ModX

class Mod_Y:
    modx_obj = ModX()

此檔案從 module_1 和 module_1_1 匯入兩個類別(ModX 和 ModA)。

mainpkg/modpkg_x/module_1.py

# module_1.py
class ModX:
   pass

from module_2 import ModY

class Mod_X:
   mody_obj = ModY()

module_1 從 module_2 匯入 ModY 類別。

mainpkg/modpkg_x/module_1_1.py

# module_2.py
class ModY:
   pass

from module_1 import ModX

module_1_1 沒有導(dǎo)入任何內(nèi)容。它不依賴任何模組。

mainpkg/modpkg_y/__init__.py

# module_1.py
class ModX:
  pass

class Mod_X:
   from module_2 import ModY
   mody_obj = ModY()

此檔案從 module_2 匯入 ModY 類別。

mainpkg/modpkg_y/module_2.py

# module_2.py
class ModY:
   pass

class Mod_Y:
   from module_1 import ModX
   modx_obj = ModX()

module_2 從 module_1_1 匯入 ModA 類別。

我們在 main.py 檔案中有以下程式碼。

root_dir/main.py

# module_1.py
import module_2 as m2

class ModX:
    def __init__(self):
        self.mody_obj = m2.ModY()

主檔案從 module_2 匯入 ModY 類別。該檔案依賴 module_2。

如果我們在這裡視覺化導(dǎo)入週期,它看起來像下面忽略 modpkg_x 和 modpkg_y 中的 __init__.py 檔案。

Different Ways to Fix Circular Imports in Python

我們可以看到主檔案依賴module_2,module_1也依賴module_2,module_2又依賴module_1_1。沒有導(dǎo)入週期。

但是你知道,模組依賴它們的 __init__.py 文件,因此 __init__.py 文件首先初始化,然後重新導(dǎo)入模組。

Different Ways to Fix Circular Imports in Python

這就是現(xiàn)在的導(dǎo)入週期。

Different Ways to Fix Circular Imports in Python

這使得 module_1_1 依賴 module_1,這是一個假依賴項。

如果是這種情況,清空子套件 __init__.py 檔案並使用單獨(dú)的 __init__.py 檔案可以幫助在套件層級集中匯入。

# module_1.py
from module_2 import ModY
class ModX:
    mody_obj = ModY()

在此結(jié)構(gòu)中,我們在 mainpkg 中加入了另一個子套件 subpkg。

mainpkg/subpkg/__init__.py

# module_2.py
from module_1 import ModX
class ModY:
    modx_obj = ModX()

這將允許內(nèi)部模組從單一來源導(dǎo)入,從而減少交叉導(dǎo)入的需要。

現(xiàn)在我們可以更新 main.py 檔案中的導(dǎo)入語句。

root_dir/main.py

Traceback (most recent call last):
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
  File "module_2.py", line 1, in <module>
    from module_1 import ModX
  File "module_1.py", line 1, in <module>
    from module_2 import ModY
ImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)

這解決了同一包內(nèi)模組之間的循環(huán)相依性問題。

結(jié)論

Python 中的循環(huán)依賴或?qū)胧且环N程式碼異味,這表明需要對程式碼進(jìn)行認(rèn)真的重構(gòu)和重構(gòu)。

您可以嘗試上述任何一種方法來避免 Python 中的循環(huán)依賴。


? 如果您喜歡這篇文章,您可能也會感興趣

?Flask 中的範(fàn)本繼承範(fàn)例。

?exec() 和 eval() 之間的差異並舉例。

?了解Python中g(shù)lobal關(guān)鍵字的使用。

?Python 類型提示:函數(shù)、傳回值、變數(shù)。

?為什麼在函數(shù)定義中使用斜線和星號。

?學(xué)習(xí)率如何影響 ML 與 DL 模型?


現(xiàn)在就這些。

繼續(xù)編碼??。

以上是在 Python 中修復(fù)循環(huán)導(dǎo)入的不同方法的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1601
29
PHP教程
1502
276
如何處理Python中的API身份驗(yàn)證 如何處理Python中的API身份驗(yàn)證 Jul 13, 2025 am 02:22 AM

處理API認(rèn)證的關(guān)鍵在於理解並正確使用認(rèn)證方式。 1.APIKey是最簡單的認(rèn)證方式,通常放在請求頭或URL參數(shù)中;2.BasicAuth使用用戶名和密碼進(jìn)行Base64編碼傳輸,適合內(nèi)部系統(tǒng);3.OAuth2需先通過client_id和client_secret獲取Token,再在請求頭中帶上BearerToken;4.為應(yīng)對Token過期,可封裝Token管理類自動刷新Token;總之,根據(jù)文檔選擇合適方式,並安全存儲密鑰信息是關(guān)鍵。

如何一次迭代兩個列表 如何一次迭代兩個列表 Jul 09, 2025 am 01:13 AM

在Python中同時遍歷兩個列表的常用方法是使用zip()函數(shù),它會按順序配對多個列表並以最短為準(zhǔn);若列表長度不一致,可使用itertools.zip_longest()以最長為準(zhǔn)並填充缺失值;結(jié)合enumerate()可同時獲取索引。 1.zip()簡潔實(shí)用,適合成對數(shù)據(jù)迭代;2.zip_longest()處理不一致長度時可填充默認(rèn)值;3.enumerate(zip())可在遍歷時獲取索引,滿足多種複雜場景需求。

什麼是Python迭代器? 什麼是Python迭代器? Jul 08, 2025 am 02:56 AM

Inpython,IteratorSareObjectSthallowloopingThroughCollectionsByImplementing_iter __()和__next __()。 1)iteratorsWiaTheIteratorProtocol,使用__ITER __()toreTurnterateratoratoranteratoratoranteratoratorAnterAnteratoratorant antheittheext__()

Python Fastapi教程 Python Fastapi教程 Jul 12, 2025 am 02:42 AM

要使用Python創(chuàng)建現(xiàn)代高效的API,推薦使用FastAPI;其基於標(biāo)準(zhǔn)Python類型提示,可自動生成文檔,性能優(yōu)越。安裝FastAPI和ASGI服務(wù)器uvicorn後,即可編寫接口代碼。通過定義路由、編寫處理函數(shù)並返回數(shù)據(jù),可以快速構(gòu)建API。 FastAPI支持多種HTTP方法,並提供自動生成的SwaggerUI和ReDoc文檔系統(tǒng)。 URL參數(shù)可通過路徑定義捕獲,查詢參數(shù)則通過函數(shù)參數(shù)設(shè)置默認(rèn)值實(shí)現(xiàn)。合理使用Pydantic模型有助於提升開發(fā)效率和準(zhǔn)確性。

如何用Python測試API 如何用Python測試API Jul 12, 2025 am 02:47 AM

要測試API需使用Python的Requests庫,步驟為安裝庫、發(fā)送請求、驗(yàn)證響應(yīng)、設(shè)置超時與重試。首先通過pipinstallrequests安裝庫;接著用requests.get()或requests.post()等方法發(fā)送GET或POST請求;然後檢查response.status_code和response.json()確保返回結(jié)果符合預(yù)期;最後可添加timeout參數(shù)設(shè)置超時時間,並結(jié)合retrying庫實(shí)現(xiàn)自動重試以增強(qiáng)穩(wěn)定性。

Python函數(shù)可變範(fàn)圍 Python函數(shù)可變範(fàn)圍 Jul 12, 2025 am 02:49 AM

在Python中,函數(shù)內(nèi)部定義的變量是局部變量,僅在函數(shù)內(nèi)有效;外部定義的是全局變量,可在任何地方讀取。 1.局部變量隨函數(shù)執(zhí)行結(jié)束被銷毀;2.函數(shù)可訪問全局變量但不能直接修改,需用global關(guān)鍵字;3.嵌套函數(shù)中若要修改外層函數(shù)變量,需使用nonlocal關(guān)鍵字;4.同名變量在不同作用域互不影響;5.修改全局變量時必須聲明global,否則會引發(fā)UnboundLocalError錯誤。理解這些規(guī)則有助於避免bug並寫出更可靠的函數(shù)。

如何用Python和Pandas解析HTML表 如何用Python和Pandas解析HTML表 Jul 10, 2025 pm 01:39 PM

是的,你可以使用Python和Pandas解析HTML表格。首先,使用pandas.read_html()函數(shù)提取表格,該函數(shù)可將網(wǎng)頁或字符串中的HTML元素解析為DataFrame列表;接著,若表格無明確列標(biāo)題,可通過指定header參數(shù)或手動設(shè)置.columns屬性修復(fù);對於復(fù)雜頁面,可結(jié)合requests庫獲取HTML內(nèi)容或使用BeautifulSoup定位特定表格;注意JavaScript渲染、編碼問題及多表識別等常見陷阱。

在Python中訪問嵌套的JSON對象 在Python中訪問嵌套的JSON對象 Jul 11, 2025 am 02:36 AM

在Python中訪問嵌套JSON對象的方法是先明確結(jié)構(gòu),再逐層索引。首先確認(rèn)JSON的層級關(guān)係,例如字典嵌套字典或列表;接著使用字典鍵和列表索引逐層訪問,如data"details"["zip"]獲取zip編碼,data"details"[0]獲取第一個愛好;為避免KeyError和IndexError,可用.get()方法設(shè)置默認(rèn)值,或封裝函數(shù)safe_get實(shí)現(xiàn)安全訪問;對於復(fù)雜結(jié)構(gòu),可遞歸查找或使用第三方庫如jmespath處理。

See all articles