python中的函式及模組
函式是帶名字的程式碼塊,要執行函式定義的特定任務,可呼叫該函式。
需要在程式中多次執行同一項任務時,你無需反覆編寫完成該任務的程式碼,而只需呼叫執行該任務的函式,通過使用函式,程式的編寫、閱讀、測試和修復都將更容易。主程式檔案的組織更為有序
一、如何定義一個函式
使用關鍵字 def 來定義一個函式。
def greeting_user(): print("Hello!,Welcome to Python World!") greeting_user()
如上述程式碼:第一行定義一個函式greeting_user,第二行為函式的功能,即列印字串 "Hello!,Welcome to Python World!"
第三行,即呼叫函式greeting_user,作用就是列印字串。
1)向函式傳遞資訊
稍作修改,在函式定義 def greeting_user() 的括號內新增 username ,可讓函式接受所給定 username 指定的任何值。
這個函式就可以呼叫給 username 指定一個值,呼叫 greeting_user() 時,可將一個名字傳遞給它,如下所示:
def greeting_user(username): print("Hello!,Welcome "+ username.title() + " use Python programing language!")
greeting_user('Bush')
greeting_user('Jack')
greeting_user('Lucy')
程式碼 greeting_user('Bush') 呼叫函式 greeting_user() ,並向它提供執行 print 語句所需的資訊。這個函式接受你傳遞給它的名字
2)實參和形參
前面定義函式 greeting_user() 時,要求給變數 username 指定一個值。呼叫這個函式並提供這種資訊(人名)時,它將列印相應的問候語。
在函式 greeting_user() 的定義中,變數 username 是一個形參—函式完成其工作所需的一項資訊。
在程式碼 greeting_user('Bush') 中,值 'Bush'、‘Jack’、‘Lucy’ 是一個實參。實參是呼叫函式時傳遞給函式的資訊,也即這幾個字串,會被傳遞給形參 username
呼叫函式時,將要讓函式使用的資訊放在括號內。在greeting_user('Bush') 中,將實參'Bush' 傳遞給了函式 greeting_user() ,這個值被儲存在形參 username 中。
二、實參
1)位置實參
由於通常函式中,會存在多個形參,呼叫函式時,Python必須將函式呼叫中的每個實參都關聯到函式定義中的一個形參。為此,最簡單的關聯方式是基於實參的順序。這種關聯方式被稱為位置實參。
def my_pet(animal_type, pet_name): print("\nI have a " + animal_type + ".") print("My " + animal_type + "'s name is " + pet_name.title() + ".") my_pet('dog', 'Wangcai')
上述程式碼中,my_pet()函式中存在兩個形參,即animal_type和pet_name,也就是在呼叫函式my_pet()時,需要2個引數,即在my_pet('dog', 'Wangcai')中,將‘dog’存入到animal_type中,‘Wangcai’存入到pet_name中,並在my_pet()中的兩個print語句中進行呼叫 。
注意:使用位置實參來呼叫函式時,如果實參的順序不正確,結果會出錯。
2)關鍵字實參
關鍵字實參是傳遞給函式的名稱-值對。直接在實參中將名稱和值關聯起來,函式傳遞實參時不會混淆。關鍵字實參讓你無需考慮函式呼叫中的實參順序,還清楚地指出了函式呼叫中各個值的用途。
my_pet(animal_type='dog', pet_name='Wangcai') my_pet(pet_name='Xiaoqiang',animal_type='cockroach')
函式 my_pet() 還是原來那樣,但呼叫這個函式時,向Python明確地指出了各個實參對應的形參。注意:上述兩個形參位置改變,在賦值的情況下,不影響程式執行。
執行結果
I have a dog. My dog's name is Wangcai. I have a cockroach. My cockroach's name is Xiaoqiang.
3)預設值
編寫函式時,可給每個形參指定預設值。如果在呼叫函式中給形參提供了實參,Python將使用指定的實參值;否則,將使用形參的預設值。因此,給形參指定預設值後,可在函式呼叫中省略相應的實參
def my_new_pet(new_pet_name,new_animal_type='dog'): print("\nI have a " + new_animal_type + ".") print("My " + new_animal_type + "'s name is " + new_pet_name.title() + ".") my_new_pet(new_pet_name='Wangcai') my_new_pet(new_pet_name='Xiaoqiang') my_new_pet(new_pet_name='Xiaoqiang',new_animal_type='cockroach')
執行結果:
I have a dog. My dog's name is Wangcai. I have a dog. My dog's name is Xiaoqiang. I have a cockroach. My cockroach's name is Xiaoqiang.
第一、二個my_new_pet()函式呼叫只給定了兩個名字,沒有給定動物型別,則函式採用預設型別‘dog’,第三個函式呼叫給定的new_animal_type='cockroach',則函式中兩個列印呼叫給定的cockroach型別。
實際執行結果:
注意:可混合使用位置實參、關鍵字實參和預設值,通常有多種等效的函式呼叫方式,如上述
my_pet(animal_type='dog', pet_name='Wangcai') my_pet(pet_name='Xiaoqiang',animal_type='cockroach')
my_new_pet(new_pet_name='Wangcai') my_new_pet(new_pet_name='Xiaoqiang') my_new_pet(new_pet_name='Xiaoqiang',new_animal_type='cockroach')
三 ,函式的返回值
函式可以處理一些資料,並返回一個或一組數值,函式返回的值被稱為返回值。在函式中,可使用 return 語句將值返回到呼叫函式的程式碼行。返回值能夠將程式的大部分繁重工作移到函式中去完成,從而簡化主程式
1)返回簡單值
def get_full_name(first_name, middle_name, last_name): #定義一個函式,有三個形參 full_name = first_name+' '+middle_name+' '+last_name #函式功能,將函式的三個形參進行連線 return full_name.title() #返回值 musician = get_full_name('Bush','lee', 'Alien') # 呼叫返回值的函式時,需要提供一個變數musician,用於儲存返回的值 # 通過函式將Bush和Alien連線後,賦值給變數musician print(musician)
2)傳遞列表
向函式傳遞列表很有用,這種列表包含的可能是名字、數字或更復雜的物件(如字典),將列表傳遞給函式,函式就能直接訪問其內容。
def menu_lists(menus): #定義一個函式,引數為列表 for menu in menus: #迴圈列表 msg = "The new menus is " + menu.title() + "!" print(msg) #列印列表 new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers'] #定義一個列表 menu_lists(new_menus) #呼叫函式menu_lists,並將列表new_menus傳遞給menu_lists(menus)中的形參menus,並執行函式中的迴圈
(1)在函式中修改列表
將列表傳遞給函式後,函式就可對其進行修改。在函式中對這個列表所做的任何修改都是永久性的,這讓你能夠高效地處理大量的資料。
completed_menus = [] #建立一個名為 completed_menus 的空列表 # 模擬列印每個設計,直到沒有未列印的選單為止 # 列印每個選單後,都將其移到列表completed_menus中 while new_menus: current_menu = new_menus.pop() #pop,從列表new_menus末尾刪除一個設計,並存放到變數名current_menu中 #模擬根據設計製作列印選單的過程 print("Printing menu: " + current_menu) completed_menus.append(current_menu) #在列表completed_menus中,逐漸存入變數名current_menu的值 #下列程式碼列印new_menus print(new_menus) #打印出列表new_menus print("\nThe following menus have been printed:")# 顯示列印好的所有選單 for completed_menu in completed_menus: #for迴圈,打印出列表completed_menus print(completed_menu)
執行結果如下:
Printing menu: Chicken Feet with Pickled Peppers Printing menu: Spicy fish pieces Printing menu: Boiled meat [] The following menus have been printed: Chicken Feet with Pickled Peppers Spicy fish pieces Boiled meat
上述程式碼執行結果:
注:程式碼重組
在(1)函式中修改列表裡列舉的程式碼,有許多的重複功能 ,可以重新組織這些程式碼,編寫兩個函式,一個函式將負責處理列印選單的工作,另一個將描寫列印了哪些選單。
#下述先定義兩個函式 def print_menus(new_menus, completed_menus): #定義一個函式將負責處理列印選單的工作 while new_menus: #當new_menus不為空 current_menu = new_menus.pop() #彈出 new_menus中最後一個元素,並賦值給變數current_menu #注意 pop()的順序是反序,也即從最後一個元素開始,到第一個元素結束。 print("Printing menus: " + current_menu) completed_menus.append(current_menu) #列表completed_models逐漸增加 def show_completed_menus(completed_models): #定義函式,顯示已列印了哪些選單 print("\nThe following models have been printed:") for completed_model in completed_models: #for迴圈,打印出數列completed_models中的元素 print(completed_model) #定義一個列表,一個空表,再呼叫上述兩個函式。 new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers'] completed_menus = [] #建立一個空表 print_menus(new_menus, completed_menus) #呼叫第一個函式,列印選單 show_completed_menus(completed_menus) #呼叫第2個函式,顯示已完成選單
執行結果:
Printing menus: Chicken Feet with Pickled Peppers Printing menus: Spicy fish pieces Printing menus: Boiled meat The following models have been printed: Chicken Feet with Pickled Peppers Spicy fish pieces Boiled meat
(2)禁止函式修改列表
在程式執行時,可能需要禁止函式修改列表。
編寫了一個將這些移到列印好的選單列表中的函式,可能會做出這樣的決定:即便列印所有選單後,也需要保留原來的未列印的選單列表,以供備案。
例如,上述列表new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers'],由於使用pop,將所有選單都移出了new_menus,使得列表new_menus變成了空的,致使原有資料丟失(如上述執行結果第4行顯示為[] )。
為解決此問題,可向函式傳遞列表的副本;這樣函式所做的任何修改都隻影響副本,而絲毫不影響原列表。切片表示法 [:] 建立列表的副本
#禁止函式修改列表 my_menus = ['meat', 'fish pieces', 'Chicken Feet'] print_menus(my_menus[:],completed_menus) print(my_menus) #重新列印列表my_menus,
如上述程式碼,重新定義一個列表my_menus ,呼叫重組後的函式print_menus,但引數只給定了my_menus[:]和completed_menus,最後重新列印列表my_menus ,檢查是否是空列表。
執行結果如下:
Printing menus: Chicken Feet Printing menus: fish pieces Printing menus: meat ['meat', 'fish pieces', 'Chicken Feet']
3)傳遞任意數量的實參
當預先不知道函式需要接受多少個實參時,Python允許函式從呼叫語句中收集任意數量的實參。函式只有一個形參 *toppings ,但不管呼叫語句提供了多少實參,這個形參都將它們統統收入囊中
形參名 *toppings 中的星號讓Python建立一個名為 toppings 的空元組,並將收到的所有值都封裝到這個元組中
def make_menus(*toppings): print("\nMaking a menus with the following toppings:") for topping in toppings: print("- " + topping) make_menus('fish') make_menus('meat', 'fish', 'beef')
執行如下:
Making a menus with the following toppings: - fish Making a menus with the following toppings: - meat - fish - beef
(1)結合使用位置實參和任意數量實參
在函式定義中將接納任意數量實參的形參放在最後。Python先匹配位置實參和關鍵字實參,再將餘下的實參都收集到最後一個形參中
def make_menus(size,*toppings): print("\nMaking a "+str(size)+" kilogram menus with the following toppings:") for topping in toppings: print("- " + topping) make_menus(2,'fish') make_menus(6,'meat', 'fish', 'beef')
執行結果如下:
Making a 2 kilogram menus with the following toppings: - fish Making a 6 kilogram menus with the following toppings: - meat - fish - beef
(2)使用任意數量的關鍵字實參
def get_person_info(given_name, family_name,**user_info): #定義一個函式,有三個形參 person_info={} #定義一個person_info person_info['first_name']=family_name #字典裡的第一個key為first_name,賦值為形參中的given_name person_info['last_name']=given_name #字典裡的第二個key為last_name,賦值為形參中的family_name for key,value in user_info.items(): person_info[key]=value return person_info user_info = get_person_info('albert','einstein',location='princetion',field = 'physics') print(user_info)
執行結果如下:
{'first_name': 'einstein', 'last_name': 'albert', 'location': 'princetion', 'field': 'physics'}
4)將函式儲存在模組中
函式的優點:
一,可將程式碼塊與主程式分離。通過給函式指定描述性名稱,讓主程式容易理解得多。
二、將函式儲存在被稱為模組的獨立檔案中,再將模組匯入到主程式中。import 語句允許在當前執行的程式檔案中使用模組中的程式碼。
通過將函式儲存在獨立的檔案中,可隱藏程式程式碼的細節,將重點放在程式的高層邏輯上,能讓你在不同的程式中重用函式。
函式儲存在獨立檔案中後,可與其他程式設計師共享這些檔案而不是整個程式。知道如何匯入函式還能讓你使用其他程式設計師編寫的函式庫
1)匯入整個模組
讓函式是可匯入的,建立模組。模組是副檔名為.py的檔案,包含要匯入到程式中的程式碼。如下圖中的建立一個包含4個不同函式的 function 的模組
在mainframe中呼叫模組function及其中的函式
import function #匯入模組function new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers'] completed_menus = [] #建立一個空表 function.print_menus(new_menus, completed_menus) #呼叫模組function中的函式print_menus function.show_completed_menus(completed_menus) #呼叫模組function中的函式show_completed_menus #禁止函式修改列表 my_menus = ['meat', 'fish pieces', 'Chicken Feet'] function.print_menus(my_menus[:],completed_menus)#呼叫模組function中的函式print_menus function.make_menus(2,'fish') function.make_menus(6,'meat', 'fish', 'beef') user_info =function.get_person_info('albert','einstein',location='princetion',field = 'physics') #呼叫模組function中的get_person_info函式 print(user_info)
2)匯入特定的函式
from function import print_menus,show_completed_menus #直接匯入某模組中的特定函式, new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers'] completed_menus = [] #建立一個空表 print_menus(new_menus, completed_menus) #呼叫函式print_menus show_completed_menus(completed_menus) #呼叫函式show_completed_menus
3) 使用 as 給模組指定別名
匯入的函式的名稱可能與程式中現有的名稱衝突,或者函式的名稱太長,可指定簡短而獨一無二的別名,類似於外號,在引用 的過程中,就相對比較方便
import function as func #給function指定一個短的名稱func new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers'] completed_menus = [] #建立一個空表 func.print_menus(new_menus, completed_menus) #呼叫函式print_menus func.show_completed_menus(completed_menus) #呼叫函式show_completed_menus
as 除了給模組指定別名,也可以給模組中的函式指定別名:
from function import print_menus as p_m from function import show_completed_menus as s_m new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers'] completed_menus = [] #建立一個空表 p_m(new_menus, completed_menus) #呼叫函式print_menus s_m(completed_menus) #呼叫函式show_completed_menus
4)匯入模組中的所有函式
from function import * new_menus = ['Boiled meat', 'Spicy fish pieces', 'Chicken Feet with Pickled Peppers'] completed_menus = [] #建立一個空表 print_menus(new_menus, completed_menus) #呼叫函式print_menus show_completed_menus(completed_menus) #呼叫函式show_completed_menus
注意區別:(1)在匯入模組時,使用函式用法:function.print_menus(new_menus, completed_menus)
(2) 匯入特定的函式時,使用函式用法:print_menus(new_menus, completed_menus)
(3)使用模組的別名時,使用函式用法:func.print_menus(new_menus, completed_menus)
import 開頭匯入的模組,在使用的時候需要帶上模組的名稱或別名( as 後面名稱)
from model import * 這種型別的則不需要,可以直接呼叫函式。