在前面的幾個章節中咱們腳本上是用 python 解釋器來編程,若是你從 Python 解釋器退出再進入,那麼你定義的全部的方法和變量就都消失了。python
爲此 Python 提供了一個辦法,把這些定義存放在文件中,爲一些腳本或者交互式的解釋器實例使用,這個文件被稱爲模塊。linux
模塊是一個包含全部你定義的函數和變量的文件,其後綴名是.py。模塊能夠被別的程序引入,以使用該模塊中的函數等功能。這也是使用 python 標準庫的方法。程序員
下面是一個使用 python 標準庫中模塊的例子。編程
執行結果以下所示:api
$ python using_sys.py 參數1 參數2 命令行參數以下: using_sys.py 參數1 參數2 Python 路徑爲: ['/root', '/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']
想使用 Python 源文件,只需在另外一個源文件裏執行 import 語句,語法以下:app
import module1[, module2[,... moduleN]
當解釋器遇到 import 語句,若是模塊在當前的搜索路徑就會被導入。ide
搜索路徑是一個解釋器會先進行搜索的全部目錄的列表。如想要導入模塊 support,須要把命令放在腳本的頂端:函數
test.py 引入 support 模塊:ui
以上實例輸出結果:spa
$ python3 test.py Hello : Runoob
一個模塊只會被導入一次,無論你執行了多少次import。這樣能夠防止導入模塊被一遍又一遍地執行。
當咱們使用import語句的時候,Python解釋器是怎樣找到對應的文件的呢?
這就涉及到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來引入一些不在搜索路徑中的模塊。
如今,在解釋器的當前目錄或者 sys.path 中的一個目錄裏面來建立一個fibo.py的文件,代碼以下:
而後進入Python解釋器,使用下面的命令導入這個模塊:
>>> import fibo
這樣作並無把直接定義在fibo中的函數名稱寫入到當前符號表裏,只是把模塊fibo的名字寫到了那裏。
可使用模塊名稱來訪問函數:
若是你打算常用一個函數,你能夠把它賦給一個本地的名稱:
>>> fib = fibo.fib >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Python 的 from 語句讓你從模塊中導入一個指定的部分到當前命名空間中,語法以下:
from modname import name1[, name2[, ... nameN]]
例如,要導入模塊 fibo 的 fib 函數,使用以下語句:
>>> from fibo import fib, fib2 >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
這個聲明不會把整個fibo模塊導入到當前的命名空間中,它只會將fibo裏的fib函數引入進來。
把一個模塊的全部內容全都導入到當前的命名空間也是可行的,只需使用以下聲明:
from modname import *
這提供了一個簡單的方法來導入一個模塊中的全部項目。然而這種聲明不應被過多地使用。
模塊除了方法定義,還能夠包括可執行的代碼。這些代碼通常用來初始化這個模塊。這些代碼只有在第一次被導入時纔會被執行。
每一個模塊有各自獨立的符號表,在模塊內部爲全部的函數看成全局符號表來使用。
因此,模塊的做者能夠放心大膽的在模塊內部使用這些全局變量,而不用擔憂把其餘用戶的全局變量搞混。
從另外一個方面,當你確實知道你在作什麼的話,你也能夠經過 modname.itemname 這樣的表示法來訪問模塊內的函數。
模塊是能夠導入其餘模塊的。在一個模塊(或者腳本,或者其餘地方)的最前面使用 import 來導入一個模塊,固然這只是一個慣例,而不是強制的。被導入的模塊的名稱將被放入當前操做的模塊的符號表中。
還有一種導入的方法,可使用 import 直接把模塊內(函數,變量的)名稱導入到當前操做模塊。好比:
>>> from fibo import fib, fib2 >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
這種導入的方法不會把被導入的模塊的名稱放在當前的字符表中(因此在這個例子裏面,fibo 這個名稱是沒有定義的)。
這還有一種方法,能夠一次性的把模塊中的全部(函數,變量)名稱都導入到當前模塊的字符表:
>>> from fibo import * >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
這將把全部的名字都導入進來,可是那些由單一下劃線(_)開頭的名字不在此例。大多數狀況, Python程序員不使用這種方法,由於引入的其它來源的命名,極可能覆蓋了已有的定義。
一個模塊被另外一個程序第一次引入時,其主程序將運行。若是咱們想在模塊被引入時,模塊中的某一程序塊不執行,咱們能夠用__name__屬性來使該程序塊僅在該模塊自身運行時執行。
#!/usr/bin/python3 # Filename: using_name.py if __name__ == '__main__': print('程序自身在運行') else: print('我來自另外一模塊')
運行輸出以下:
$ python using_name.py 程序自身在運行
$ python
>>> import using_name 我來自另外一模塊 >>>
說明: 每一個模塊都有一個__name__屬性,當其值是'__main__'時,代表該模塊自身在運行,不然是被引入。
說明:__name__ 與 __main__ 底下是雙下劃線, _ _ 是這樣去掉中間的那個空格。
內置的函數 dir() 能夠找到模塊內定義的全部名稱。以一個字符串列表的形式返回:
>>> import fibo, sys >>> dir(fibo) ['__name__', 'fib', 'fib2'] >>> dir(sys) ['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__', '__package__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe', '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount', 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'version'