簡體   English   中英

Python 模塊的絕對與顯式相對導入

[英]Absolute vs. explicit relative import of Python module

我想知道在 Python 應用程序中導入包的首選方法。 我有這樣的包結構:

project.app1.models
project.app1.views
project.app2.models

project.app1.views導入project.app1.modelsproject.app2.models 我想到了兩種方法來做到這一點。

絕對進口:

import A.A
import A.B.B

或者使用顯式相對導入,如Python 2.5 和 PEP 328中引入的那樣:

# explicit relative
from .. import A
from . import B

最pythonic的方法是什么?

不再強烈反對 Python 相對導入,但在這種情況下強烈建議使用 absolute_import。

請參閱引用 Guido 本人的討論

“這主要不是歷史嗎?在實施新的相對導入語法之前,相對導入存在各種問題。短期解決方案是建議不要使用它們。長期解決方案是實施明確的語法。現在現在是撤回反推薦的時候了。當然,不過分——我仍然發現它們是一種后天習得的品味;但它們有自己的位置。”

OP 正確鏈接了PEP 328 ,它說:

介紹了幾個用例,其中最重要的是能夠重新排列大型包的結構而無需編輯子包。 此外,如果沒有相對導入,包內的模塊無法輕松導入自身。

另請參閱幾乎重復的問題When or why to use relative imports in Python

當然,這仍然是一個品味問題。 雖然使用相對導入更容易移動代碼,但這也可能出乎意料地破壞事情; 重命名導入並不困難。

要強制使用 PEP 328 的新行為,請使用:

from __future__ import absolute_import

在這種情況下,隱式相對導入將不再可能(例如import localfile將不再起作用,只能from. import localfile )。 對於干凈和面向未來的行為,建議使用 absolute_import 。

一個重要的警告是,由於PEP 338PEP 366 ,相對導入需要將 python 文件作為模塊導入 - 你不能執行具有相對導入的 file.py 否則你會得到一個ValueError: Attempted relative import in non-package

在評估最佳方法時應考慮到這一限制。 Guido 反對在任何情況下從模塊運行腳本:

我對此以及 __main__ 機器的任何其他提議的擺弄都是-1。 唯一的用例似乎是運行恰好位於模塊目錄中的腳本,我一直將其視為反模式。 要讓我改變主意,你必須說服我事實並非如此。

關於這個問題的詳盡討論可以在 SO 上找到; 回覆。 Python 3 這是相當全面的:

絕對進口。 來自 PEP 8:

強烈建議不要使用包內導入的相對導入。 始終對所有導入使用絕對包路徑。 即使現在 PEP 328 [7] 已在 Python 2.5 中完全實現,其顯式相對導入的風格仍被積極勸阻; 絕對導入更便攜,通常更易讀。

顯式相對導入是一個很好的語言特性(我猜),但它們遠不如絕對導入那么顯式。 更具可讀性的形式是:

import A.A
import A.B.B

特別是如果您導入多個不同的命名空間。 如果你看一些寫得很好的項目/教程,其中包括從包中導入,它們通常遵循這種風格。

為使其他人(也許還有您)在將來試圖弄清楚您的名稱空間(尤其是如果您遷移到 3.x,其中一些包名稱已更改)。

相對導入不僅讓你以后可以自由地重命名你的包,而無需更改幾十個內部導入,而且我還成功地解決了涉及循環導入或命名空間包等問題的某些問題,因為它們不會將 Python“送回” top" 從頂級命名空間重新開始搜索下一個模塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM