Python 學習:003day——模塊,搜索路徑與包

模塊

把這些定義存放在文件中,爲一些腳本或者交互式的解釋器實例使用,這個文件被稱爲模塊。模塊是一個包含所有你定義的函數和變量的文件,其後綴名是.py。模塊可以被別的程序引入,以使用該模塊中的函數等功能。這也是使用 python 標準庫的方法。

搜索路徑

搜索路徑是由一系列目錄名組成的,Python解釋器就依次從這些目錄中去尋找所引入的模塊。這看起來很像環境變量❤,事實上,也可以通過定義環境變量的方式來確定搜索路徑。

搜索路徑是在Python編譯或安裝的時候確定的,安裝新的庫應該也會修改。☺搜索路徑☺被存儲在🐷sys模塊中的path變量🐷,做一個簡單的實驗,在交互式解釋器中,輸入以下代碼:

`>>> import sys`
`>>> sys.path`
['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']`

sys.path 輸出是一個列表,其中:
🙃第一項是空串’’,代表當前目錄(若是從一個腳本中打印出來的話,可以更清楚地看出是哪個目錄),亦即我們👍執行python解釋器的目錄(對於腳本的話就是運行的腳本所在的目錄)。

因此若像我一樣在當前目錄下存在與要引入模塊同名的文件,就會把要引入的模塊屏蔽掉。

瞭解了搜索路徑的概念,就可以在腳本中修改sys.path來引入一些不在搜索路徑中的模塊。

import與from…import…

from … import 語句
Python 的 from 語句讓你從模塊中導入一個指定的部分到當前命名空間中

包是一種管理 Python 模塊命名空間的形式,採用"點模塊名稱"。比如一個模塊的名稱是 A.B, 那麼他表示一個包 A中的子模塊 B 。

就好像使用模塊的時候,你不用擔心不同模塊之間的全局變量相互影響一樣,採用點模塊名稱這種形式也不用擔心不同庫之間的模塊重名的情況。

這樣不同的作者都可以提供 NumPy 模塊,或者是 Python 圖形庫。

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

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

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

從一個包中導入*

設想一下,如果我們使用 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"]

這表示當你使用from sound.effects import *這種用法時,你只會導入包裏面這三個子模塊。

如果 all 真的沒有定義,那麼使用from sound.effects import *這種語法的時候,就不會導入包 sound.effects 裏的任何子模塊。他只是把包sound.effects和它裏面定義的所有內容導入進來(可能運行__init__.py裏定義的初始化代碼)。

這會把 init.py 裏面定義的所有名字導入進來。並且他不會破壞掉我們在這句話之前導入的所有明確指定的模塊。看下這部分代碼:

import sound.effects.echo
import sound.effects.surround
from sound.effects import *

這個例子中,在執行from…import前,包sound.effects中的echo和surround模塊都被導入到當前的命名空間中了。(當然如果定義了__all__就更沒問題了)

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

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

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

引用:
http://www.runoob.com/python3/python3-module.html

???

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章