1. 程式人生 > 其它 >python中的函式及模組

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 *  這種型別的則不需要,可以直接呼叫函式。