一個Python Module(模塊),是一個文件,包含了Python對象定義和Python語句(definitions and statements)。文件名就是模塊名加上后綴.py,在模塊內部,模塊名存儲在全局變量__name__中,是一個string,可以直接在module中通過__name__引用到module name。
module是為了重復使用一些對象,比如類,函數,而將這些對象定義放在一個.py文件中,或是將一個較大的工程裁縫為多個.py文件而易於維護,每一個.py文件都是一個module。
1,模塊的定義和引入(import)
如下一個fibo.py文件
1 print ("__name__ :", __name__) 2 def fib(n): 3 a, b = 0, 1 4 result = [] 5 print ("in fib():", __name__) 6 while (b<n): 7 result.append(b) 8 a, b = b, a+b
9 print(result)
這個fibo.py就是一個module,它有一個函數定義fib(),和一個語句(statement),第一行的print語句,我們在當前文件目錄運行Python Interpreter就可以去引入這個模塊,並執行模塊中定義的fib()函數。
>>> import fibo ('__name__ :', 'fibo') #print語句執行 >>> fibo.fib(10) ('in fib() :', 'fibo') #fib()函數執行 [1, 1, 2, 3, 5, 8]
可以看到,在import的時候,這個module的語句(statements)執行了,所定義的函數並未執行,在通過module名引用module中的函數定義時,函數才被執行
同樣可以在一個script file中引入module,我們在fibo.py所在的目錄創建另一個文件calculat.py
1 from fibo import fib
2 for n in range(10, 50, 5): 3 fib(n)
然后用Python解釋器運行calcute.py得到結果。
這里有兩種import 語句,
一種是import module_name1 [as name1], module_name2 [as name2]
一種是from module_name import item1 [as name1], item2 [as name2]
2, module的加載
每個module都包含對象定義和一些語句(statements),這些語句應該是意圖要來初始化這個module的,這些語句會在這個module第一次被import的時候執行(多次import只會執行一次,不管是以上兩種import的語句中那一種),當這個module被作為一個script來運行的時候也會被執行。
每個module都有自己的private symbol table,當使用第一種import語句import一個module的時候,引入者的local symbol table就加入了這個module,其名字如果沒有使用as的話就是被引入的模塊名本身。使用第二種import語句這會在引入者的local symbol table中加入具體引用的item,其名稱若沒使用as則就為item的名稱。
3,module搜索路徑
當遇到一個名為xiaoyu的module需要import的時候,Python Interpreter首先搜尋built-in module中有沒有叫這個名的,若是沒有,則Interpreter會從一系列的目錄中去搜尋這個module(也就是這個.py文件),這些目錄值存儲在sys.path中,而sys.path又是用這些值來初始化的:
- 當前目錄,即input script所在的目錄
- 環境變量PYTHONPATH中存儲的值(PYTHONPATH的語法和PATH一樣)
- Python包的安裝目錄,比如我的服務器上django就安裝在 /usr/local/lib/python2.7/dist-packages/中,sys.path含有這個目錄
Python有一個標准庫,其中定義了一系列的module,這些module中的一部分是直接集成在Interpreter中的,這些built-in module主要提供了很重要的但是Python語言又沒有提供的功能,比如跟system call有關的sys module就集成在所有平台的Python Interpreter中,在Interpreter中集成哪些module是可以配置的,並且隨平台不同而有差別。
在啟動Interpreter,sys.path被初始化后,我們可以對它進行修改
>>> import sys >>> sys.path.append('/root/home/project/code/python')
4, 把module作為script來執行
前面我們已經提到了關於module中語句的執行。這里要補充一點東西,通常一個script file指的是調用Python Interpreter時作為參數傳遞給Interpreter的文件,當然所有的.py文件都是一個module,這樣的一個script或是module,其__name__會被Interpreter自動設置為"__main__"。以下是一個測試:
1 print ("__name__ :", __name__) 2 def fib(n): 3 a, b = 0, 1 4 result = [] 5 print ("in fib() :", __name__) 6 while (b<n): 7 result.append(b) 8 a, b = b, a+b 9 print(result) 10 11 if __name__ == "__main__": 12 import sys
13 fib(int(sys.argv[1]))
用Python Interpreter直接調用這個script
oot@AY1212240253255e84714:/home/project/code/python# python fibo.py 22 ('__name__ :', '__main__') ('in fib() :', '__main__') [1, 1, 2, 3, 5, 8, 13, 21]
可以看到依然module的語句都會被執行,只是__name__的值一開始就變為了"__main__",給一個模塊加上
if __name == "__main__":
常常是為了測試這個模塊,因為這個語句塊只有當module被作為script直接傳給Interpreter的時候才會被執行。
上面例子中的12行import sys可以看出,Python並沒有規定import語句必須寫在module的最前面,只是習慣性的我們約定都寫在最前面。
5. 內置dir()函數(built-in dir() function)
dir()函數可以用來查看一個module所定義的所有names,試驗
>>> dir() ['__builtins__', '__doc__', '__name__', '__package__'] >>> import sys, fibo as fibo_local ('__name__ :', 'fibo') >>> dir() ['__builtins__', '__doc__', '__name__', '__package__', 'fibo_local', 'sys'] >>> dir(fibo) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'fibo' is not defined >>> dir(fibo_local) ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'fib']
可以看到在import了fibo和sys后,並且fibo是用別名fibo_local來引入的,在引入者module中就定義了sys和fibo_local,可以看到dir(fibo)是拋了NameError異常的,fibo並沒有被定義,定義的是fibo_local,這也可以看出import語句對local symbol table是怎樣影響的。
6, 模塊包(package)
包(package)可以理解為是組織起來的module的一個層次結構,也就是package是一個directory,它包含sub-package或者是module,而module是.py文件,要讓Python Interpreter把一個目錄作為package,則該目錄下必須有__init__.py文件,__init__.py可以為空,當然也可以有對象定義和語句,用來做初始化工作,__init__.py還有個作用就是設置__all__變量。
package本身就可以來作為一個module使用,只是它所包含的sub-module或module可以通過package name用package.module的名稱形式去引用,這更有利於組織一系列相關的module,避免module間定義的名稱的混亂。
package在實際工程中非常常用,__init__.py也常常不會為空,而會有對象定義和初始化代碼來讓這個包,也就是這個module,包含其該有的item定義。以后我們會對package做更多了解。
參考:
1,http://docs.python.org/3.3/tutorial/modules.html modules
2,http://docs.python.org/3.3/reference/simple_stmts.html#the-import-statement import語句
3,http://docs.python.org/3/reference/executionmodel.html Python execution model
4,http://docs.python.org/3/reference/import.html Python import system