2009-08-11 48 views
6

導入哪些模塊,可以說,我在一個文件叫我和openid.py我做的:的Python:如何選擇時,它們被命名爲同一

from openid.consumer.discover import discover, DiscoveryFailure 

我有openid模塊上我的PYTHONPATH但口譯員似乎試圖使用我的openid.py文件。我如何獲得圖書館版本?

(當然,除了顯而易見的'重命名你的文件'的答案會很好)。

+7

「重命名文件」 – SilentGhost 2009-08-11 08:49:31

+0

什麼是不重命名文件的原因是什麼?這看起來像是一個小小的修復,而不是尋找一種解決方法。 – Zoomulator 2009-08-11 09:31:12

+0

該文件應該在語義上稱爲openid,因爲它位於帶有「類型」別名的模塊中。 openid是類型的名稱。 – 2009-08-11 09:46:34

回答

9

這就是絕對導入被選爲新的默認行爲的原因。但是,它們還不是2.6的默認值(可能在2.7 ...)。您可以通過從未來進口他們現在得到他們的行爲:

from __future__ import absolute_import 

您可以在文檔中"What's New in Python 2.5"找到更多關於這個由尼克metnioned的PEP或(更容易理解,我認爲)。

3

重命名它。這是命名空間背後的想法。您的openid可能是您頂級模塊project中的一個子模塊。您的email將與stdlib中的頂級模塊email發生衝突。

因爲你的openid不是通用的,它爲你的項目提供了一個特例。

+4

實際上,我認爲名稱空間背後的想法是*不*必須將其重命名爲獨特的東西;)myproject.openid與openid不同。 使用新的絕對導入,導入openid將始終獲得系統範圍(例如stdlib)模塊,相對.openid將獲取當前模塊中的openid子模塊。 – c089 2009-08-11 09:32:46

+0

當然不是。 **如果**他的模塊「project」比他應該使用'project.openid'。目前還不清楚爲什麼OP在做他正在做的事情,但是如果他沒有模塊「project」,那麼他應該將'openid'重命名爲其他東西。 – SilentGhost 2009-08-11 10:35:26

+0

正確。在包之外它是pkg.openid。但在「openid.py」文件中,我無法訪問「openid」庫。這是主要問題。 – 2009-08-11 22:48:27

1

您可以使用相對或絕對進口(取決於您的具體情況),最近在PEP 328中涵蓋。當然,嚴重的是,你不應該像這樣創建命名衝突,應該重命名你的文件。

+0

即使文件的語義正確名稱是openid?就像它是否在一個別名類型的目錄一樣,電子郵件,網頁,域等? – 2009-08-11 09:08:55

+0

@保羅:即使那樣。如果它位於「別名類型目錄」中,那麼它確實應該是一個包,然後是pkg.openid,這是明確的。 – 2009-08-11 20:34:43

+0

正確。在包之外它是pkg.openid。但在「openid.py」文件中,我無法訪問「openid」庫。這是主要問題。 – 2009-08-11 22:47:51

-1

你可以嘗試洗牌sys.path,做進口之前有趣的目錄移動到前面。

+0

如果已經設置了'sys.modules ['openid']',它就不會有幫助,因爲在'openid.py'中就是OP。 – 2009-08-11 15:08:59

+0

@Alex爲什麼會這樣?當前文件是否自動添加到sys.modules?一個快速的test.py <「import sys; print sys.modules.keys()」,運行時會有其他建議! – ThomasH 2009-08-11 16:20:28

+0

將_imported_模塊以真實名稱添加到sys.modules中;作爲「主程序」運行的一個文件取而代之的是傳統名稱「__main__」。但是,如果您將openid.py作爲主模塊運行,那麼沒有理由首先將它放在sys.path上! – 2009-08-12 00:58:37

2

我不會進入重命名上的論戰,而是專注於你展示如何做你想做的(不管它是「對你有好處」或不;-)。解決方案並不難...

只需設置__path__!小演示:

$ mkdir /tmp/modules /tmp/packages 
$ mkdir /tmp/packages/openid 
$ echo 'print "Package!"' > /tmp/packages/openid/__init__.py 
$ gvim /tmp/modules/openid.py 
$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid' 
Module! 
Package! 

這顯示了模塊 OpenID的管理,即使該模塊的路徑來此前在sys.path中,sys.modules['openid']顯然已經設置在那個時候導入同名。和所有的「祕密」是openid.py的簡單的代碼...:

print "Module!" 
__path__ = ['/tmp/packages'] 
import openid 

沒有__path__分配,當然,也只是發出Module!

也適用於包內的進口,當然子模塊。做:

$ echo 'print "Submod!"' > /tmp/packages/openid/submod.py 

並改變openid。PY的最後一行

from openid import submod 

,你會看到:

$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid' 
Module! 
Package! 
Submod! 
$ 
+0

關於sys.modules ['openid']被設置。你也在另一個評論中這樣說,但我不太確定。爲什麼會是這種情況?當前文件是否自動添加到sys.modules?一個快速的test.py <「導入sys;在sys.modules.keys()中打印'test',運行時會有其他建議! – ThomasH 2009-08-11 21:06:54

+0

正如我回復其他評論:作爲主要模塊運行的一個文件進入'sys.modules ['__ main __']'而不是(因爲它的'__name__'被人爲地和常規地設置爲'__main__')。這就是爲什麼我在這裏輸入** openid來表示'__path__'仍然有效。如果所有你需要的w/openid.py是運行它爲主,那麼沒有理由在sys.path中。 – 2009-08-12 01:01:05

+0

我認爲OP的問題僅僅來自'。'這一事實。在sys.path中較早出現,所以在當前目錄中搜索找到導入openid.py腳本的'openid'。但是,如果您將sys.path的「有趣」目錄轉移到其前面,則首先會找到另一個「openid」(模塊),並且一切都很好。 – ThomasH 2009-08-12 08:10:37

相關問題