2010-03-02 85 views
29

在Python中,import *究竟導入了什麼?它是否在包含文件夾中找到__init__.py「導入*」導入到底是什麼?

例如,是否有必要聲明from project.model import __init__或者from project.model import *是否足夠?

+0

'from yadda.yadda import *'在黑客攻擊Python命令行中的內容時非常有用,例如,當你使用Python作爲計算器時,你只需輸入'from math import *'。在一個模塊中,它要求麻煩。另外,如果您導入單個文件模塊(而不是目錄),'from ... import *'將不會導入名稱以'_'開頭的符號。 – 2010-03-02 03:51:46

回答

38

相對於其他形式進口的from xyz import *的「好處」是,進口一切(好,幾乎... [見(a)所示]的所有內容)從當前模塊下指定的模塊。這允許使用來自導入模塊的各種對象(變量,類別,方法...),而無需在模塊的名稱前添加。例如

>>> from math import * 
>>>pi 
3.141592653589793 
>>>sin(pi/2) 
>>>1.0 

這種做法(輸入*到當前的命名空間),然而,鼓勵,因爲它 它

  • 提供了機會,命名空間衝突(比方說,如果你有一個變量名PI在導入之前)
  • 可能效率低下,如果導入的對象數量很大。
  • 沒有明確文件變量/方法/類的起源(它是好的,有計劃的對未來的此次訪問「自文檔」到代碼中)

通常我們因此限制了這種進口*實踐即席測試之類的,而是:

明確導入幾個對象只

>>>from math import pi 
>>>pi 
>>>3.141592653589793 
>>> sin(pi/2) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'sin' is not defined 

導入模根據其自己的名稱空間 ULE(或別名物,特別是如果這是一個長的名稱,並且該程序引用其對象多次)

>>>import math 
    >>>math.pi 
    >>>3.141592653589793 
    etc.. 


    >>>import math as m #bad example math being so short and standard... 
    >>>m.pi 
    >>>3.141592653589793 
    etc.. 

參見Python documentation on this topic

的(a)具體地,與from xyz import *導入的內容
如果xyz模塊定義了一個__all__變量,它將導入在此序列中定義的所有名稱,否則它將導入所有名稱,除了以下劃線開頭的所有名稱。

+7

'從X導入*'的優點是它可以讓你很懶惰。它的問題是,它會咬你懶惰的屁股:) – voyager 2010-03-02 04:14:19

+1

一些模塊(如['pygame'](http://www.pygame.org/docs/ref/locals.html),但許多其他)有一個特殊的子模塊,目的是作爲'*'導入。這些特殊模塊通常具有常用的常量或功能。 – 2011-01-25 01:55:43

+0

因此,基本上我可以導入一切,而不會得到名稱空間衝突,如果我使用'import math'而不是'從數學導入*'? – 2014-11-16 13:59:17

3

是的,它的確如此。它會導入所有內容(這不是私有變量,即:名稱以___開頭的變量),您應該儘量不要根據「Properly importing modules in Python」使用它以避免污染本地名稱空間。

這是不夠的,但通常您應該做import project.model,已經進口__init__.py,每個「Understanding python imports」,但可以得到,如果你使用它太多,或import project.model as pmimport project.model as model節省幾個按鍵後來當太羅嗦你用吧。

按照亞歷克斯在諮詢「What exactly does "import *" import?

+6

良好的推薦,但不準確的信息:'從foo導入*'不**「導入所有內容」 - 它導入模塊的__all__屬性中列出的名稱,或者缺少該屬性_non-private_ names(不包括以'_'開頭的名稱)。 – 2010-03-02 03:50:48

+0

@亞歷克斯,好點。你想擴大它,還是你更喜歡我這麼做? – voyager 2010-03-02 04:13:04

+0

我已經擴充了它 - 請參閱我對這個問題的回答。 – 2010-03-02 04:16:07

2

如果project.model是一個包,通過import project.model提到的模塊是從.../project/model/__init__.pyfrom project.model import *__init__.py的命名空間中的所有內容都轉儲爲您的。它不會自動對模型中的其他模塊執行任何操作。首選的樣式是__init__.py不包含任何內容。

永遠不會永遠使用import *。它使你的代碼不可讀,不可維護。

1

如果有問題的模塊(project.model)已經定義了名爲__all__的響應列表,那麼該列表中的每個命名變量都會被導入。如果沒有這樣的變量,它會導入一切。

10

它將模塊(或包)在其__all__屬性中列出的任何名稱(到當前名稱空間中)導入 - 缺少這樣的屬性,所有名稱不以_開頭。

它主要用作只在交互式解釋器會話中使用一個方便快捷:其他答案建議,在程序中使用它。

我的建議,每Google's Python style guide,是永遠只導入模塊,從模塊中類或函數(或其他名稱)。嚴格遵循這一點可以提高清晰度和精確度,並避免在從模塊中導入「材料」時可能出現的細微陷阱。

導入程序包(或其中的任何內容)會固有加載並執行程序包的__init__.py - 該文件定義程序包的主體。但是,它不會在當前名稱空間中綁定名稱__init__(因此從這個意義上說,它不會導入該名稱)。

+0

所以基本上我可以導入一切都沒有得到名稱空間相撞,如果我使用'導入數學'而不是'從數學導入*'? – 2014-11-16 13:59:46