你已經(jīng)學(xué)習(xí)了如何在你的程序中定義一次函數(shù)而重用代碼。如果你想要在其他程序中重用很多函數(shù),那么你該如何編寫程序呢?你可能已經(jīng)猜到了,答案是使用模塊。模塊基本上就是一個包含了所有你定義的函數(shù)和變量的文件。為了在其他程序中重用模塊,模塊的文件名必須以.py 為擴(kuò)展名。
模塊可以從其他程序 輸入 以便利用它的功能。這也是我們使用 Python 標(biāo)準(zhǔn)庫的方法。首先,我們將學(xué)習(xí)如何使用標(biāo)準(zhǔn)庫模塊。
例 8.1 使用 sys 模塊
#!/usr/bin/python
# Filename: using_sys.py
import sys
print 'The command line arguments are:'
for i in sys.argv:
print i
print '\n\nThe PYTHONPATH is', sys.path, '\n'
(源文件:code/using_sys.py)
輸出
$ python using_sys.py we are arguments
The command line arguments are:
using_sys.py
we
are
arguments
The PYTHONPATH is ['/home/swaroop/byte/code', '/usr/lib/python23.zip',
'/usr/lib/python2.3', '/usr/lib/python2.3/plat-linux2',
'/usr/lib/python2.3/lib-tk', '/usr/lib/python2.3/lib-dynload',
'/usr/lib/python2.3/site-packages', '/usr/lib/python2.3/site-packages/gtk-2.0']
它如何工作
首先,我們利用 import 語句 輸入 sys 模塊?;旧希@句語句告訴 Python,我們想要使用這個模塊。sys 模塊包含了與 Python 解釋器和它的環(huán)境有關(guān)的函數(shù)。
當(dāng) Python 執(zhí)行 import sys 語句的時候,它在 sys.path 變量中所列目錄中尋找 sys.py 模塊。如果找到了這個文件,這個模塊的主塊中的語句將被運(yùn)行,然后這個模塊將能夠被你 使用 。注意,初始化過程僅在我們 第一次 輸入模塊的時候進(jìn)行。另外,“sys”是“system”的縮寫。
sys 模塊中的 argv 變量通過使用點(diǎn)號指明——sys.argv——這種方法的一個優(yōu)勢是這個名稱不會與任何在你的程序中使用的 argv 變量沖突。另外,它也清晰地表明了這個名稱是 sys 模塊的一部分。
sys.argv 變量是一個字符串的 列表(列表會在后面的章節(jié)詳細(xì)解釋)。特別地,sys.argv 包含了 命令行參數(shù) 的列表,即使用命令行傳遞給你的程序的參數(shù)。
如果你使用 IDE 編寫運(yùn)行這些程序,請在菜單里尋找一個指定程序的命令行參數(shù)的方法。
這里,當(dāng)我們執(zhí)行 python using_sys.py we are arguments 的時候,我們使用 python 命令運(yùn)行 using_sys.py 模塊,后面跟著的內(nèi)容被作為參數(shù)傳遞給程序。Python 為我們把它存儲在 sys.argv 變量中。
記住,腳本的名稱總是 sys.argv 列表的第一個參數(shù)。所以,在這里,'using_sys.py'是sys.argv[0]、'we'是 sys.argv[1]、'are'是sys.argv[2]以及'arguments'是 sys.argv[3]。注意,Python 從 0 開始計數(shù),而非從 1 開始。
sys.path 包含輸入模塊的目錄名列表。我們可以觀察到 sys.path 的第一個字符串是空的——這個空的字符串表示當(dāng)前目錄也是 sys.path 的一部分,這與 PYTHONPATH 環(huán)境變量是相同的。這意味著你可以直接輸入位于當(dāng)前目錄的模塊。否則,你得把你的模塊放在 sys.path 所列的目錄之一。
輸入一個模塊相對來說是一個比較費(fèi)時的事情,所以 Python 做了一些技巧,以便使輸入模塊更加快一些。一種方法是創(chuàng)建 字節(jié)編譯的文件 ,這些文件以.pyc作為擴(kuò)展名。字節(jié)編譯的文件與 Python 變換程序的中間狀態(tài)有關(guān)(是否還記得 Python 如何工作的介紹?)。當(dāng)你在下次從別的程序輸入這個模塊的時候,.pyc 文件是十分有用的——它會快得多,因?yàn)橐徊糠州斎肽K所需的處理已經(jīng)完成了。另外,這些字節(jié)編譯的文件也是與平臺無關(guān)的。所以,現(xiàn)在你知道了那些.pyc 文件事實(shí)上是什么了。
如果你想要直接輸入 argv 變量到你的程序中(避免在每次使用它時打 sys.),那么你可以使用 from sys import argv 語句。如果你想要輸入所有 sys 模塊使用的名字,那么你可以使用 from sys import *語句。這對于所有模塊都適用。一般說來,應(yīng)該避免使用 from..import 而使用 import 語句,因?yàn)檫@樣可以使你的程序更加易讀,也可以避免名稱的沖突。
每個模塊都有一個名稱,在模塊中可以通過語句來找出模塊的名稱。這在一個場合特別有用——就如前面所提到的,當(dāng)一個模塊被第一次輸入的時候,這個模塊的主塊將被運(yùn)行。假如我們只想在程序本身被使用的時候運(yùn)行主塊,而在它被別的模塊輸入的時候不運(yùn)行主塊,我們該怎么做呢?這可以通過模塊的 name 屬性完成。
例 8.2 使用模塊的 name
#!/usr/bin/python
# Filename: using_name.py
if __name__ == '__main__':
print 'This program is being run by itself'
else:
print 'I am being imported from another module'
(源文件:code/using_name.py)
輸出
$ python using_name.py
This program is being run by itself
$ python
>>> import using_name
I am being imported from another module
>>>
```
它如何工作
每個 Python 模塊都有它的 name,如果它是'main',這說明這個模塊被用戶單獨(dú)運(yùn)行,我們可以進(jìn)行相應(yīng)的恰當(dāng)操作。
創(chuàng)建你自己的模塊是十分簡單的,你一直在這樣做!每個 Python 程序也是一個模塊。你已經(jīng)確保它具有.py 擴(kuò)展名了。下面這個例子將會使它更加清晰。
例 8.3 如何創(chuàng)建你自己的模塊
#!/usr/bin/python
# Filename: mymodule.py
def sayhi():
print 'Hi, this is mymodule speaking.'
version = '0.1'
# End of mymodule.py
(源文件:code/mymodule.py)
上面是一個 模塊 的例子。你已經(jīng)看到,它與我們普通的 Python 程序相比并沒有什么特別之處。我們接下來將看看如何在我們別的 Python 程序中使用這個模塊。
記住這個模塊應(yīng)該被放置在我們輸入它的程序的同一個目錄中,或者在 sys.path 所列目錄之一。
#!/usr/bin/python
# Filename: mymodule_demo.py
import mymodule
mymodule.sayhi()
print 'Version', mymodule.version
(源文件:code/mymodule_demo.py)
輸出
$ python mymodule_demo.py
Hi, this is mymodule speaking.
Version 0.1
它如何工作
注意我們使用了相同的點(diǎn)號來使用模塊的成員。Python 很好地重用了相同的記號來,使我們這些 Python 程序員不需要不斷地學(xué)習(xí)新的方法。
下面是一個使用 from..import 語法的版本。
#!/usr/bin/python
# Filename: mymodule_demo2.py
from mymodule import sayhi, version
# Alternative:
# from mymodule import *
sayhi()
print 'Version', version
(源文件:code/mymodule_demo2.py)
mymodule_demo2.py 的輸出與 mymodule_demo.py 完全相同。
你可以使用內(nèi)建的 dir 函數(shù)來列出模塊定義的標(biāo)識符。標(biāo)識符有函數(shù)、類和變量。
當(dāng)你為 dir()提供一個模塊名的時候,它返回模塊定義的名稱列表。如果不提供參數(shù),它返回當(dāng)前模塊中定義的名稱列表。
例 8.4 使用 dir 函數(shù)
$ python
>>> import sys
>>> dir(sys) # get list of attributes for sys module
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',
'__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',
'builtin_module_names', 'byteorder', 'call_tracing', 'callstats',
'copyright', 'displayhook', 'exc_clear', 'exc_info', 'exc_type',
'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval',
'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding',
'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',
'meta_path','modules', 'path', 'path_hooks', 'path_importer_cache',
'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',
'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',
'version', 'version_info', 'warnoptions']
>>> dir() # get list of attributes for current module
['__builtins__', '__doc__', '__name__', 'sys']
>>>
>>> a = 5 # create a new variable 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
>>>
>>> del a # delete/remove a name
>>>
>>> dir()
['__builtins__', '__doc__', '__name__', 'sys']
>>>
它如何工作
首先,我們來看一下在輸入的 sys 模塊上使用 dir。我們看到它包含一個龐大的屬性列表。
接下來,我們不給 dir 函數(shù)傳遞參數(shù)而使用它——默認(rèn)地,它返回當(dāng)前模塊的屬性列表。注意,輸入的模塊同樣是列表的一部分。
為了觀察 dir 的作用,我們定義一個新的變量 a 并且給它賦一個值,然后檢驗(yàn) dir,我們觀察到在列表中增加了以上相同的值。我們使用del語句刪除當(dāng)前模塊中的變量/屬性,這個變化再一次反映在 dir 的輸出中。
關(guān)于 del 的一點(diǎn)注釋——這個語句在運(yùn)行后被用來 刪除 一個變量/名稱。在這個例子中,del a,你將無法再使用變量 a——它就好像從來沒有存在過一樣。
模塊的用處在于它能為你在別的程序中重用它提供的服務(wù)和功能。Python 附帶的標(biāo)準(zhǔn)庫就是這樣一組模塊的例子。我們已經(jīng)學(xué)習(xí)了如何使用這些模塊以及如何創(chuàng)造我們自己的模塊。
接下來,我們將學(xué)習(xí)一些有趣的概念,它們稱為數(shù)據(jù)結(jié)構(gòu)。