設想一下,如果我們使用 from sound.effects import *會發(fā)生什么?python 會進入文件系統(tǒng),找到這個包里面所有的子模塊,一個一個的把它們都導入進來。
但是很不幸,這個方法在 windows平臺上工作的就不是非常好,因為windows是一個大小寫不區(qū)分的系統(tǒng)。
在這類平臺上,沒有人敢擔保一個叫做 echo.py 的文件導入為模塊 echo 還是 echo 甚至 echo。
(例如,windows 95就很討厭的把每一個文件的首字母大寫顯示)而且 dos 的 8 3 命名規(guī)則對長模塊名稱的處理會把問題搞得更糾結。
為了解決這個問題,只能煩勞包作者提供一個精確的包的索引了。
導入語句遵循如下規(guī)則:如果包定義文件 __init__.py 存在一個叫做 __all__ 的列表變量,那么在使用 from package import * 的時候就把這個列表中的所有名字作為包內(nèi)容導入。
作為包的作者,可別忘了在更新包之后保證 __all__ 也更新了啊。你說我就不這么做,我就不使用導入*這種用法,好吧,沒問題,誰讓你是老板呢。這里有一個例子,在:file:sounds/effects/__init__.py中包含如下代碼:
這表示當你使用from sound.effects import *這種用法時,你只會導入包里面這三個子模塊。
如果 __all__ 真的沒有定義,那么使用from sound.effects import *這種語法的時候,就不會導入包 sound.effects 里的任何子模塊。他只是把包sound.effects和它里面定義的所有內(nèi)容導入進來(可能運行__init__.py里定義的初始化代碼)。
這會把 __init__.py 里面定義的所有名字導入進來。并且他不會破壞掉我們在這句話之前導入的所有明確指定的模塊??聪逻@部分代碼:
這個例子中,在執(zhí)行 from…import 前,包 sound.effects 中的 echo 和 surround 模塊都被導入到當前的命名空間中了。(當然如果定義了 __all__ 就更沒問題了)
通常我們并不主張使用 * 這種方法來導入模塊,因為這種方法經(jīng)常會導致代碼的可讀性降低。不過這樣倒的確是可以省去不少敲鍵的功夫,而且一些模塊都設計成了只能通過特定的方法導入。
記住,使用 from package import specific_submodule 這種方法永遠不會有錯。事實上,這也是推薦的方法。除非是你要導入的子模塊有可能和其他包的子模塊重名。
如果在結構中包是一個子包(比如這個例子中對于包sound來說),而你又想導入兄弟包(同級別的包)你就得使用導入絕對的路徑來導入。比如,如果模塊sound.filters.vocoder 要使用包 sound.effects 中的模塊 echo,你就要寫成 from sound.effects import echo。
無論是隱式的還是顯式的相對導入都是從當前模塊開始的。主模塊的名字永遠是__main__,一個python應用程序的主模塊,應當總是使用絕對路徑引用。
包還提供一個額外的屬性__path__。這是一個目錄列表,里面每一個包含的目錄都有為這個包服務的__init__.py,你得在其他__init__.py被執(zhí)行前定義哦??梢孕薷倪@個變量,用來影響包含在包里面的模塊和子包。
這個功能并不常用,一般用來擴展包里面的模塊。