函數是帶名字的代碼塊,要執行函數定義的特定任務,可調用該函數。 需要在程式中多次執行同一項任務時,你無需反覆編寫完成該任務的代碼,而只需調用執行該任務的函數,通過使用函數,程式的編寫、閱讀、測試和修複都將更容易。主程式文件的組織更為有序 一、如何定義一個函數 使用關鍵字 def 來定義一個函數。 d ...
函數是帶名字的代碼塊,要執行函數定義的特定任務,可調用該函數。
需要在程式中多次執行同一項任務時,你無需反覆編寫完成該任務的代碼,而只需調用執行該任務的函數,通過使用函數,程式的編寫、閱讀、測試和修複都將更容易。主程式文件的組織更為有序
一、如何定義一個函數
使用關鍵字 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 * 這種類型的則不需要,可以直接調用函數。