2009-12-16 42 views
12

我有兩個相關的Python導入問題。它們很容易測試,但我想要的是語言定義的而不是實現特定的答案,而且我對樣式/約定也很感興趣,所以我在這裏問。Python導入機制

1)

如果模塊A導入模塊B和模塊B模塊進口C,可以在模塊沒有明確的進口代碼的引用模塊C?如果是這樣,我認爲這是不好的做法是正確的嗎?

2)

如果我導入模塊A.B.C,是否進口模塊A和A·B以及?如果是這樣,是否明確規定import A; import A.B; import A.B.C

+0

「語言定義的而不是實現特定的」你是說Python實現有些不同嗎?你知道哪些具體的差異? AFAIK沒有。 – 2009-12-16 21:49:45

+0

也許沒有任何區別,但是規範未定義的任何內容都取決於實現。 Python文檔散佈着關於CPython實現細節的警告,這些細節可能不適用於其他實現。 – 2009-12-16 21:52:38

回答

12

您應該知道的第一件事是Python語言不是ISO標準。這與C/C++有很大不同,這意味着沒有「正確」的方式來定義語言行爲--CPython可能會做某些事情,只是因爲它是以這種方式編碼的,而Jython可能會這樣做。

關於您的問題,請記住,「導入」模塊是一個由兩部分組成的操作:首先裝載模塊 - 如果它從未如此,例如如果它在sys.modules中不可用,那麼名稱將綁定到本地名稱空間中的該模塊。

因此:

1)是,可以通過提供適當的命名空間,例如引用任何你從模塊一個想你必須做一些像

BCname =「東西」

而且我認爲這是在Python程序很少做,可以被認爲是不好的做法,因爲它迫使「傳遞DEP」 - 如果一些模塊B實現被重構並且不再依賴於C,它應該繼續提供C模塊來滿足A代價。

課程設置__ __都可以防止這種情況,和一個很好的做法可能是把所有__ __在所有的模塊,並導出只是你想成爲真正的公共符號。 2)是和不是。做

import a.b.c.d 

執行所有模塊上的第一導入階段(裝載),但第二隻是一個(並且遞歸地,在b相對於C,等),但在鏈中的所有模塊都必須被全名稱空間引用;這樣的導入後,你可以做

a.something 
a.b.something 
a.b.c.something 

,但你不能做

c.something 
b.something 

我必須承認,一種用法是非常罕見的爲好;我通常更喜歡「從模塊導入某種東西」的方式導入,通常你只是問你需要什麼 - 這種嵌套在圖書館中既不常見,也不常見。

很多時候,「外包裝」只是用於組織,它們擁有類的模塊。上面的a,b,c很可能只是包,而d是一個真正擁有類,函數和其他對象的模塊。所以正確的用法是:

from a.b.c.d import name1, name2, name3 

我希望這能滿足你的好奇心。

+0

感謝您的詳細解答! – 2009-12-16 23:03:00

+0

雖然不是ISO,但有一個定義「正確」行爲的Python語言參考,包括導入:http://docs.python.org/reference/simple_stmts.html#the-import-statement 語言參考指出CPython的實現細節,但其目標是成爲該語言的通用規範,因此它不是全部依賴於實現。 – 2009-12-17 09:09:10

11

艾倫給出了一個很好的答案,但我想補充說,對於你的問題1,這取決於你的意思是「進口」。

如果使用from C import x語法,則在B的名稱空間中可用x。如果在A中,然後您做import B,您有權訪問xA作爲B.x

這不是太糟糕的做法,因爲可能會讓人困惑,並且會使調試更困難,因爲您不一定知道對象來自哪裏。

+0

這是一個有用的說明,謝謝。我一直認爲'import'與Java風格的軟件包導入類似,但顯然這種相似性僅僅是膚淺的。 – 2009-12-16 23:05:04

+0

如果令人困惑,是不是有足夠的理由稱之爲壞習慣?應該明白什麼代碼只是通過閱讀它恕我直言。 – jjpe 2015-04-14 18:06:27