【筆記】Python3導入包規則


 

 

例如:這里給出了一種可能的包結構(在分層的文件系統中):

sound/                          頂層包
      __init__.py               初始化 sound 包
      formats/                  文件格式轉換子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  聲音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

 

目錄只有包含一個叫做 __init__.py 的文件才會被認作是一個包,主要是為了避免一些濫俗的名字(比如叫做 string)不小心的影響搜索路徑中的有效模塊。

最簡單的情況,放一個空的 :file:__init__.py就可以了。當然這個文件中也可以包含一些初始化代碼或者為(將在后面介紹的) __all__變量賦值。

 

from package import item

當導入使用:from package import item這種形式的時候,對應的item既可以是包里面的子模塊(子包),或者包里面定義的其他名稱,比如函數,類或者變量。

import語法會首先把item當作一個包定義的名稱,如果沒找到,再試圖按照一個模塊去導入。如果還沒找到,恭喜,一個:exc:ImportError 異常被拋出了。

 

import item.subitem.subsubitem

反之,如果使用形如import item.subitem.subsubitem這種導入形式,除了最后一項,都必須是包,而最后一項則可以是模塊或者是包,但是不可以是類,函數或者變量的名字。

 

通常我們並不主張使用*這種方法來導入模塊,因為這種方法經常會導致代碼的可讀性降低。不過這樣倒的確是可以省去不少敲鍵的功夫,而且一些模塊都設計成了只能通過特定的方法導入。

記住,使用from Package import specific_submodule這種方法永遠不會有錯。事實上,這也是推薦的方法。除非是你要導入的子模塊有可能和其他包的子模塊重名。

 

如果在結構中包是一個子包(比如這個例子中對於包sound來說),而你又想導入兄弟包(同級別的包)你就得使用導入絕對的路徑來導入。比如,如果模塊sound.filters.vocoder 要使用包sound.effects中的模塊echo,你就要寫成 from sound.effects import echo。

在導入一個包的時候,Python 會根據 sys.path 中的目錄來尋找這個包中包含的子目錄。

import sound.effects.echo

這將會導入子模塊:sound.effects.echo。 他必須使用全名去訪問:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

還有一種導入子模塊的方法是:

from sound.effects import echo 

這同樣會導入子模塊: echo,並且他不需要那些冗長的前綴,所以他可以這樣使用:

echo.echofilter(input, output, delay=0.7, atten=4)

還有一種變化就是直接導入一個函數或者變量:

from sound.effects.echo import echofilter

同樣的,這種方法會導入子模塊: echo,並且可以直接使用他的 echofilter() 函數:

echofilter(input, output, delay=0.7, atten=4)

 

從一個包中導入*

設想一下,如果我們使用 from sound.effects import *會發生什么?

Python 會進入文件系統,找到這個包里面所有的子模塊,一個一個的把它們都導入進來。

但是很不幸,這個方法在 Windows平台上工作的就不是非常好,因為Windows是一個大小寫不區分的系統。

在這類平台上,沒有人敢擔保一個叫做 ECHO.py 的文件導入為模塊 echo 還是 Echo 甚至 ECHO。

(例如,Windows 95就很討厭的把每一個文件的首字母大寫顯示)而且 DOS 的 8+3 命名規則對長模塊名稱的處理會把問題搞得更糾結。

為了解決這個問題,只能煩勞包作者提供一個精確的包的索引了。

導入語句遵循如下規則:如果包定義文件 __init__.py 存在一個叫做 __all__ 的列表變量,那么在使用 from package import * 的時候就把這個列表中的所有名字作為包內容導入。

 

作為包的作者,可別忘了在更新包之后保證 __all__ 也更新了啊。你說我就不這么做,我就不使用導入*這種用法,好吧,沒問題,誰讓你是老板呢。這里有一個例子,在:file:sounds/effects/__init__.py中包含如下代碼:

__all__ = ["echo", "surround", "reverse"]

  

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM