2012-12-06 38 views
2

我需要一些關於在同一名稱空間中共存時如何處理模塊和類級別導入的說明。參看下面的例子:瞭解Python導入優先級

作品:

import datetime 
print datetime.datetime.utcnow() 

失敗:

from datetime import datetime 
print datetime.datetime.utcnow() 

Error: AttributeError: type object 'datetime.datetime' has no attribute 'datetime'

作品:

from datetime import datetime # Is this ignored? 
import datetime 
print datetime.datetime.utcnow() 

第三個例子究竟發生了什麼?第二個模塊導入替換了特定於類的第一個導入嗎?這是否意味着模塊和類級別的導入不應混合在相同的名稱空間中?

回答

5

沒有優先權是這樣的。結果取決於執行import報表的順序,如下所示。

如果您嘗試將幾個名爲X的東西導入到您的名稱空間中,則每個導入都會重新綁定X以導入任何內容。

因此在最後它將是最後一次導入,其實際上就名稱X而言是有效的。

這是你的第三個例子恰恰發生了什麼:

from datetime import datetime # This isn't ignored, but the name is immediately rebound 
           # by the next line 
import datetime    # Rebinds the name 
+0

讓人有道理感謝 – Yarin

2

的一些IDE的支持巨蟒會給你的解釋,但是,是的,你重新定義(覆蓋,更換)進口的第三個例子。文件中的每個名稱都是不同的。如果你需要訪問一個模塊和一個共享名字的類,你需要使用類似from datetime import datetime as dt的東西。

0

你的第一示例導入datetime模塊,並提供在本地名稱空間中的標籤datetime表示它,然後調用屬於datetime模塊datetime對象的utcnow()方法。第二個將datetime.datetime對象(不是模塊)添加到標號爲datetime的本地名稱空間,但datetime對象沒有屬性datetime,因此您將得到該異常。第三個示例將datetime.datetime對象分配給名稱空間中該名稱的標籤,然後將標籤重新分配給datetime模塊。所以忽略不相關對這個問題的import機制(基本上,增加模塊sys.modules如果他們現在還沒有),你有什麼等價於:

datetime = sys.modules['datetime'] 
datetime.datetime.utcnow() 

然後

​​

然後

datetime = sys.modules['datetime'].datetime 
datetime = sys.modules['datetime'] 
datetime.datetime.utcnow() 
0

沒有理由做這樣的:

from datetime import datetime 
print datetime.datetime.utcnow() 

這個代碼,而另一方面,會做的正是你希望它是什麼:

from datetime import datetime 
print datetime.utcnow() 
1

的進口實際上只是一個任務:它設置在當前的命名空間的名稱。因此,在第三種情況下,您將名稱datetime設置爲等於datetime類,然後立即將其重新分配給日期時間模塊。