Python語言程序設(shè)計》 —1.3.5 輸入和輸出">《Python語言程序設(shè)計》 —1.3.5 輸入和輸出
584
2025-04-03
3.3 模塊
如前面介紹,Python提供了交互式和腳本式兩種運行方式。當(dāng)要執(zhí)行的代碼比較長且需要重復(fù)使用時,我們通常將代碼放在擴(kuò)展名為.py的Python腳本文件中。當(dāng)我們要編寫一個規(guī)模比較大的程序時,如果將所有代碼都放在一個腳本文件中,則不方便維護(hù)和多人協(xié)同開發(fā)。另外,對于可以在多個程序中重用的功能,也最好將其放在單獨的腳本文件中,以方便多個程序通過引用該腳本文件來共享這些功能。此時,我們需要按照代碼功能的不同,將代碼分門別類地放在不同的腳本文件中,這些腳本文件稱為模塊(module)。
當(dāng)要使用一個模塊中的某些功能時,我們可以通過import方式導(dǎo)入該模塊。例如,假設(shè)模塊A中定義了一些變量和函數(shù),如果希望在模塊B中使用它們,則可以在模塊B中通過import將模塊A導(dǎo)入,此時在模塊B中就可以使用這些變量并調(diào)用模塊A的所有函數(shù)。
3.3.1 import
使用import語句導(dǎo)入模塊的語法如下:
import module1
import module2
…
import moduleN
也可以在一行內(nèi)導(dǎo)入多個模塊:
import module1, module2, ..., moduleN
下面通過一個具體的例子說明模塊使用的方法。首先,我們定義一個名字為fibo.py的腳本文件,其中包括PrintFib和GetFib兩個函數(shù)的定義,參見代碼清單3-11。
代碼清單3-11 fibo.py腳本文件
1??? def PrintFib(n): #定義函數(shù)PrintFib,輸出斐波那契數(shù)列的前n項
2??????? a, b = 1, 1 #將a和b都賦為1
3??????? for i in range(1,n+1): #i的取值依次為1,2,…,n
4??????????? print(a, end=' ') #輸出斐波那契數(shù)列的第i項
5??????????? a, b = b, a+b #更新斐波那契數(shù)列第i+1項的值,并計算第i+2項的值
6??????? print() #輸出一個換行
7??? def GetFib(n): #定義函數(shù)GetFib,返回斐波那契數(shù)列的前n項
8??????? fib=[] #定義一個空列表fib
9??????? a, b = 1, 1 #將a和b都賦為1
10?????? for i in range(1,n+1): #i的取值依次為1,2,…,n
11?????????? fib.append(a) #將斐波那契數(shù)列的第i項存入列表fib中
12?????????? a, b = b, a+b #更新斐波那契數(shù)列第i+1項的值,并計算第i+2項的值
13?????? return fib #將列表fib返回
14?? PrintFib(10) #調(diào)用PrintFib輸出斐波那契數(shù)列前10項
15?? ls=GetFib(10) #調(diào)用GetFib函數(shù)獲取斐波那契數(shù)列前10項組成的列表
16?? print(ls) #輸出列表ls中的元素
程序執(zhí)行完畢后,將在屏幕上輸出如下結(jié)果:
1 1 2 3 5 8 13 21 34 55
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
提示 斐波那契數(shù)列(Fibonacci sequence)又稱黃金分割數(shù)列,因數(shù)學(xué)家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數(shù)列”。斐波那契數(shù)列前兩項的值都為1,后面每一項的值等于其前兩項的和,即F(1)=F(2)=1,F(xiàn)(n)=F(n-1)+F(n-2)(n>2)。
下面我們再編寫一個名為testfibo.py的腳本文件,參見代碼清單3-12。
代碼清單3-12 testfibo.py腳本文件
1??? import fibo #導(dǎo)入fibo模塊
2??? fibo.PrintFib(5) #調(diào)用fibo模塊中的PrintFib函數(shù),輸出斐波那契數(shù)列前5項
3??? ls=fibo.GetFib(5) #調(diào)用fibo模塊中的GetFib函數(shù),得到斐波那契數(shù)列前5項的列表
4??? print(ls) #輸出ls中保存的斐波那契數(shù)列前5項
程序執(zhí)行完畢后,將在屏幕上輸出如下結(jié)果:
1 1 2 3 5 8 13 21 34 55
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
1 1 2 3 5
[1, 1, 2, 3, 5]
提示 導(dǎo)入模塊后,如果要使用該模塊中定義的標(biāo)識符,則需要通過“模塊名.標(biāo)識符名”的方式。
從程序的輸出結(jié)果可以看到,雖然我們只在testfibo.py中輸出了斐波那契數(shù)列的前5項,但當(dāng)執(zhí)行import fibo時,也執(zhí)行了fibo.py中第14~16行代碼,所以會同時輸出斐波那契數(shù)列的前10項數(shù)據(jù)。下面我們考慮一下如何避免這個問題,使得一個腳本文件單獨運行時就執(zhí)行這些語句;而作為模塊導(dǎo)入時,就不執(zhí)行這些語句。要實現(xiàn)這個功能,需要用到每個模塊中都有的一個全部變量__name__。__name__的作用是獲取當(dāng)前模塊的名稱,如果當(dāng)前模塊是單獨執(zhí)行的,則其__name__的值就是__main__;否則,如果是作為模塊導(dǎo)入,則其__name__的值就是模塊的名字。例如,對于代碼清單3-13和代碼清單3-14:
代碼清單3-13 module.py腳本文件
1??? print(__name__) #輸出全局變量__name__的值
代碼清單3-14 testmodule.py腳本文件
1??? import module #導(dǎo)入module模塊
當(dāng)執(zhí)行module.py時,會在屏幕上輸出__main__;而當(dāng)執(zhí)行testmodule.py時,則會在屏幕上輸出module。也就是說,module.py單獨運行和作為模塊導(dǎo)入時,其__name__的值是不同的。因此,我們可以將代碼清單3-11加以修改,參見代碼清單3-15中加粗部分。
代碼清單3-15 修改后的fibo.py腳本文件
1??? def PrintFib(n): #定義函數(shù)PrintFib,輸出斐波那契數(shù)列的前n項
2??????? a, b = 1, 1 #將a和b都賦為1
3??????? for i in range(1,n+1): #i的取值依次為1,2,…,n
4??????????? print(a, end=' ') #輸出斐波那契數(shù)列的第i項
5??????????? a, b = b, a+b #更新斐波那契數(shù)列第i+1項的值,并計算第i+2項的值
6??????? print() #輸出一個換行
7??? def GetFib(n): #定義函數(shù)GetFib,返回斐波那契數(shù)列的前n項
8??????? fib=[] #定義一個空列表fib
9??????? a, b = 1, 1 #將a和b都賦為1
10?????? for i in range(1,n+1): #i的取值依次為1,2,…,n
11?????????? fib.append(a) #將斐波那契數(shù)列的第i項存入列表fib中
12?????????? a, b = b, a+b #更新斐波那契數(shù)列第i+1項的值,并計算第i+2項的值
13?????? return fib #將列表fib返回
14?? if __name__=='__main__': #只有單獨執(zhí)行fibo.py時該條件才成立
15?????? PrintFib(10) #調(diào)用PrintFib輸出斐波那契數(shù)列前10項
16?????? ls=GetFib(10) #調(diào)用GetFib函數(shù)獲取斐波那契數(shù)列前10項組成的列表
17?????? print(ls) #輸出列表ls中的元素
此時,當(dāng)執(zhí)行fibo.py時,將在屏幕上輸出如下結(jié)果:
1 1 2 3 5 8 13 21 34 55
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
當(dāng)執(zhí)行testfibo.py時,將在屏幕上輸出如下結(jié)果:
1 1 2 3 5
[1, 1, 2, 3, 5]
即修改后的fibo.py中的第15~17行代碼因條件不成立而沒有執(zhí)行。
除了可以導(dǎo)入自己編寫的模塊外,也可以直接導(dǎo)入系統(tǒng)提供的模塊,使用其中的功能。例如,我們可以通過sys模塊獲取運行Python腳本時傳入的參數(shù),如代碼清單3-16所示。
代碼清單3-16 修改后的testfibo.py腳本文件
1??? import fibo #導(dǎo)入fibo模塊
2??? import sys #導(dǎo)入系統(tǒng)提供的sys模塊
3??? n=int(sys.argv[1]) #通過sys模塊的argv獲取執(zhí)行腳本時傳入的參數(shù)
4??? fibo.PrintFib(n) #調(diào)用fibo模塊中的PrintFib函數(shù),輸出斐波那契數(shù)列前n項
5??? ls=fibo.GetFib(n) #調(diào)用fibo模塊中的GetFib函數(shù),得到斐波那契數(shù)列前n項的列表
6??? print(ls) #輸出ls中保存的斐波那契數(shù)列前n項
在系統(tǒng)控制臺下,如果執(zhí)行python testfibo.py 5,則會輸出如下結(jié)果:
1 1 2 3 5
[1, 1, 2, 3, 5]
如果執(zhí)行python testfibo.py 10,則會輸出如下結(jié)果:
1 1 2 3 5 8 13 21 34 55
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
提示 讀者可嘗試在一個Python腳本文件中導(dǎo)入sys模塊后,執(zhí)行print(sys.argv),即可看到輸出的一個列表,其中第一個元素是腳本文件名,后面的元素是運行腳本文件時傳入的參數(shù)。
Python
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。