簡介模組


你可以撰寫一個純文字檔案,建議副檔名為.py,在當中撰寫Python程式碼:
  • hello.py
print('Hello!Python!')

接著如下執行指令載入指令稿直譯並執行:
>python hello.py
Hello!Python!


如果你想取得命令列引數(Command line argument),則可以使用sys.argv,例如:
  • hello.py
import sys
print('Hello!' + sys.argv[1] + '!')

要取得命令列引數,必須先以import語句匯入sys模組(Module),命令列引數字串陣列方式收集並指定給sys.argv,索引0表示為 第一個命令列引數,在Python中就是存放所執行的.py檔名,索引1則表示第二個命令列引數,依此類推。接著如下執行指令載入指令稿直譯並執行:
> python hello.py caterpillar
Hello!caterpillar!


所謂模組,實際上就是個.py檔案。import語句匯入模組實際上就是載入另一個.py檔案並執行其內容。例如可先撰寫一個.py檔案:
  • some.py
name = 'Justin'
print(name)

接著在另一個.py檔案中或指令互動模式中使用import語句並執行相關程式碼:
>>> import some
Justin
>>> print(name)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'name' is not defined
>>> print(some.name)
Justin
>>> from some import name
>>> print(name)
Justin
>>> name = 'Monica'
>>> print(name)
Monica
>>> print(some.name)
Justin


import some時,實際上會載入some.py,之後將其編譯為位元碼形式,若有儲存檔案的權限,則通常會將位元碼儲存為.pyc檔案,位元碼是個與平台相依的指令格式,如果下次再匯入模組時,原始碼並沒有更動且.pyc存在,就會直接載入.pyc,減少了直譯的時間,從而加快了執行的速度。例如,在執行過以上的指令後,你可以發現some.pyc的存在。

使 用import匯入模組後,就會執行程式,所以上例中,你馬上看到some.py中print函式的結果。模組其實也是個名稱空間,模組名稱就是檔案名 稱,模組中宣告的變數或函式都是模組中的屬性,若要存取模組中的變數或函式等名稱,必須前置模組名稱,例如some.title這樣的名稱。

可以使用from import語句在目前模組中,建立與被匯入模組中某些變數相同的名稱,並將值指定給新建立的變數名稱。正如上面所示範的,建立出與被匯入模組中相同的變數名稱是為了方便取用變數。如果你想要知道模組中的屬性名稱,則可以使用dir()函式:
>>> dir(some)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'name']
>>> 


在上例中,因為some.name參考的是不可變動的字串,因此重新指定值給目前模組中的name,並不會影響some.name。但如果是可變動物件,例如:
  • other.py
list = [1, 2, 3]
print(list)

則會有以下的結果:
>>> import other
[1, 2, 3]
>>> from other import list
>>> list
[1, 2, 3]
>>> list[0] = 100
>>> list
[100, 2, 3]
>>> other.list
[100, 2, 3]
>>>


除了你自定義的屬性之外,還有一些內建的屬性,這之後有機會再深入介紹。你可以一次匯入兩個以上的名稱,例如:
from some import x, y

或者是將模組中的名稱全部匯入,例如:
from some import *

import 語句或from import語句只會在第一次匯入模組時執行模組中的程式碼,重複import同一個模組,並不會使得模組中的程式碼被重複執行多次,正如上例中所看到 的,你並沒有看到some.py中的print函式重複被執行。如果你想要重新執行模組,則可以使用imp.reload()函式。例如:
>>> import imp
>>> imp.reload(some)
Justin
<module 'some' from 'some.py'>
>>>
 


附帶一提的是,如果要直接載入某個.py檔案來執行,則可以使用open()開啟.py檔案,之後read()讀取檔案,再使用exec()來執行,注意!這並非import,也非imp.reload(),只是讀取整個原始碼,再整個執行過一遍。例如:
>>> exec(open('some.py').read())
Justin


每個.py檔案都是Python的模組,你可以將個別的功能撰寫在不同的模組中,在必要的時候以import語句匯入模組,就可以取用特定模組的功能,這是撰寫Python程式的一個中心架構。

先前談到,可以使用dir()查詢模組中的屬性,這邊先介紹一下__name__屬性。如果你使用python指令直接執行某個.py檔案,則__name__屬性會被設定為'__main__'名稱,如果是import語句匯入模組,則__name__會被設定為模組名稱。所以,模組的作者會為了測試自己所設計的模組,而寫下這樣的程式碼:
  • some.py
def doSome(text):
return text + '...processed...'

def main():
fixture = 'orz'
print(doSome(fixture))

if __name__ == '__main__':
main()

如此,只有在直接執行some.py時,才會呼叫main()函式並執行測試,若使用import語句匯入模組則不會。

在入門階段,可以先知道的是,Python會在PYTHONPATH環境變數所設定的路徑中,尋找.py或.pyc模組檔案,實際上,PYTHONPATH環境變數的內容會被讀取,成為sys.path陣列中的字串元素,而這個字串所代表的路徑,正是模組檔案尋找的根據:
>>> import sys
>>> sys.path
['', 'C:\Windows\system32\python31.zip', 'c:\winwar
e\python31\DLLs', 'c:\winware\python31\lib', 'c:\winware\python31\lib\p
lat-win', 'c:\winware\python31', 'c:\winware\python31\lib\site-packages']
>>>