1. 程式人生 > 實用技巧 >【Python基礎知識】(七)函式和模組

【Python基礎知識】(七)函式和模組

函式的基本概念

def greet_user( username ):
    print( "Hello, " + username.title() + "!" )

greet_user( 'jesse' )

輸出為:

Hello, Jesse!

  這是一個比較簡單的函式。其中第一行叫做函式定義,它向Python指出了函式名,還在括號中包含了這個函式為完成其任務所需要的資訊,這些參量被稱作形參。緊跟在定義語句後面的所有縮排行構成了函式體

  第四行是函式呼叫,它讓Python執行函式的程式碼。括號內的參量被稱作實參,這個值在呼叫函式被儲存在形參中,為函式完成對應工作提供必要資訊。

傳遞實參的幾種方式

1、位置實參

  按形參的排列順序,依次給出對應的實參。

def describe_pet( animal_type, pet_name ):
    print( "I have a " + animal_type + "." )
    print( "My " + animal_type + "'s name is " + pet_name.title() + "." )

describe_pet( 'hamster' , 'harry' )

輸出為:

I have a hamster.
My hamster's name is Harry.

2、關鍵字實參

  關鍵字實參是傳遞給函式的名稱-值對,在實參中直接將名稱和值關聯起來,因此向函式傳遞實參時不會混淆。

  當使用關鍵字實參時,可隨意改變不同實參間的排列順序,而傳遞的結果不變(只要不改變名稱-值對應關係)。

def describe_pet( animal_type, pet_name ):
    print( "I have a " + animal_type + "." )
    print( "My " + animal_type + "'s name is " + pet_name.title() + "." )

describe_pet( animal_type = 'hamster
' , pet_name = 'harry' ) '''下面這種函式呼叫與上面等效''' describe_pet( pet_name = 'harry' , animal_type = 'hamster' )

3、給定預設值

  定義函式時,可為每個形參指定預設值。當呼叫函式時沒有給出這些形參對應的實參時,它們會預設將各自的預設值作為實參執行;當給出對應實參時,則會使用這些實參執行

def describe_pet( pet_name , animal_type = 'dog' ):
    print( "I have a " + animal_type + "." )
    print( "My " + animal_type + "'s name is " + pet_name.title() + "." )

describe_pet( pet_name = 'willie' )

  #注意:給定預設值的形參要排在後面沒有給定預設值的排在前面,否則編譯器會報錯。

複雜的傳參問題

1、傳遞任意數量的參量

  當預先不知道函式需要多少個參量時使用

def make_pizza( *toppings ):
'''列印所有配料'''
print( "\nMaking a pizza with the following toppings:" )
for topping in toppings:
print( "- " + topping )

make_pizza( 'pepperoni' )
make_pizza( 'mushrooms' , 'green peppers' , 'extra cheese' )

輸出為:


Making a pizza with the following toppings:
- pepperoni

Making a pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese

  其中形參名*toppings中的星號*讓Python建立一個名為toppings的空元組,並將收到的所有值都裝進這個元組中。

2、結合使用位置實參和任意數量實參

  如果要讓函式接受不同型別的實參,必須在函式定義中將接納任意數量實參的形參放在最後。Python先匹配位置實參和關鍵字實參,再將餘下的實參都收集到最後一個形參中。

def make_pizza( size, *toppings ):
    '''概述要製作的披薩'''
    print( "\nMaking a " + str( size ) + 
            "-inch pizza with the following toppings:" )
    for topping in toppings:
        print( "- " + topping )
        
make_pizza( 16, 'pepperoni' )
make_pizza( 12, 'mushrooms' , 'green peppers' , 'extra cheese' )

輸出為:

Making a 16-inch pizza with the following toppings:
- pepperoni

Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese

3、使用任意數量的關鍵字實參

def build_profile( first, last, **user_info ):
    '''建立一個字典,包含使用者的相關資訊'''
    profile = { }
    profile[ 'first_name' ] = first
    profile[ 'last_name' ] = last
    for key, value in user_info.items():
        profile[ key ] = value
    return profile
    
user_profile = build_profile( 'albert' , 'einstein' ,
                              location = 'prinston' , 
                              field = 'physics' )
print( user_profile )                           

輸出為:

{'first_name': 'albert', 'last_name': 'einstein', 'location': 'prinston', 'field': 'physics'}

  其中形參名**user_info中的兩個星號讓Python建立一個名為user_info的空字典,並將接收到的名稱-值對都封裝在這個字典中。在這個函式中,可以像訪問其他字典那樣訪問user_info中的名稱-值對。

返回值

  函式返回主程式的值被稱為返回值。可使用return語句將值返回到呼叫函式的程式碼行,從而簡化主程式。

1、返回簡單值

def get_formatted_name( first_name, last_name )
    full_name = first_name + " " + last_name
    return full_name.title()

musician = get_formatted_name( 'jimi' , 'hendrix' )
print( musician )

輸出為:

Jimi Hendrix

2、讓實參變成可選的

  當不是所有情況都要返回一個變數時,可通過給它們對應的形參指定一個預設值——空字串的方式,讓這個實參變成可選的

def get_formatted_name( first_name, last_name, middle_name = '' ):
    if middle_name:
        full_name = first_name + " " + middle_name + " " + last_name
    else:
        full_name = first_name + " " + last_name
    return full_name.title()

musician = get_formatted_name( 'jimi' , 'hendrix' )
print( musician )
musician = get_formatted_name( 'john' , 'hooker' , 'lee' )
print( musician )

輸出為:

Jimi Hendrix
John Lee Hooker

3、返回字典

def build_person( first_name, last_name, age = '' ):
    person = { 'first' : first_name, 'last' : last_name }
    if age:
        person[ 'age' ] = age
    return person

musician = build_person( 'jimi' , 'hendrix' , age = 27 )
print( musician )

輸出為:

{'first': 'jimi', 'last': 'hendrix', 'age': 27}

向函式傳遞列表

1、簡單的列表傳遞

def greet_users( names ):
    for name in names:
        message = "Hello " + name.title() + "!"
        print( message )

usernames = [ 'hannah' , 'ty' , 'margot' ]
greet_users( usernames )

輸出為:

Hello Hannah!
Hello Ty!
Hello Margot!

2、在函式中修改列表

  改寫以下程式:

'''建立一個列表,其中包含一些要列印的設計'''
unprinted_designs = [ 'iphone case' , 'robot pendant' , 'dodecahedron' ]
completed_models = [ ]

'''列印每個設計,直到沒有未列印的設計為止'''
'''列印每個設計後,都將其移到列表unprinted_models中'''
while unprinted_designs:
    current_design = unprinted_designs.pop()
    
    print( "Printing model: " + current_design )
    completed_models.append( current_design )

'''顯示列印好的所有模型'''    
print( "\nThe following models have been printed:" )
for completed_model in completed_models:
    print( completed_model )

該程式輸出為:

Printing model: dodecahedron
Printing model: robot pendant
Printing model: iphone case

The following models have been printed:
dodecahedron
robot pendant
iphone case

  引入兩個函式來實現相同的功能:

def print_models( unprinted_designs, completed_models ):
    '''列印每個設計,然後將它們移至列表completed_models中'''
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        
        print( "Printing model: " + current_design )
        completed_models.append( current_design )
        
def show_completed_models( completed_models ):
    '''顯示列印好的所有模型'''
    print( "\nThe following models have been printed:" )
    for completed_model in completed_models:
        print( completed_model )

'''主程式'''        
unprinted_designs = [ 'iphone case' , 'robot pendant' , 'dodecahedron' ]
completed_models = [ ]

print_models( unprinted_designs, completed_models )
show_completed_models( completed_models )

3、保留原有列表

  可通過向函式傳遞切片表示法([ : ])所建立的列表的副本而不是原件的方式,使函式中的相關修改隻影響列表的副本而不是原件,從而保留原來的列表

'''傳遞格式如下'''
function_name( list_name[ : ] )
'''例如'''
print_models( unprinted_designs[ : ], completed_models )

模組

  將函式儲存在被稱為模組的獨立檔案中,再將模組匯入到主程式中。使用import語句可在當前執行的程式檔案中使用模組中的程式碼。

  使用模組可以讓你把重點放在程式的高層邏輯上,還能讓你在其他程式中使用該程式中的函式。

1、建立模組

  模組是副檔名為.py的檔案,包含想要匯入到其他程式中的函式程式碼,如:

def make_pizza( size, *toppings ):
    '''概述要製作的披薩'''
    print( "\nMaking a " + str( size ) + 
            "-inch pizza with the following toppings:" )
    for topping in toppings:
        print( "- " + topping )

'''將上面的程式碼儲存在名為pizza.py的檔案中'''

2、匯入模組及呼叫模組中函式的幾種方式

(1)匯入整個模組

語法:
import module_name
module_name.function_name()
如:
import pizza
pizza.make_pizza( 16, 'pepperoni' )

  Python讀取這個檔案時,程式碼行import pizza讓Python開啟檔案pizza.py,並將其中所有函式都複製到這個程式中。使得在當前檔案中,可以使用pizza.py中定義的所有函式。

  當要匯入的模組與程式中現有的名稱衝突過長或因其他原因不能使用原來的名稱時,可以用as為其指定別名

語法:
import module_name as mn
mn.function_name()
如:
import pizza as p
p.make_pizza( 16, 'pepperoni' )

(2)匯入特定的函式

語法:
from module_name import function_name
function_name()
如:
from pizza import make_pizza
make_pizza( 16, 'pepperoni' )

  與模組同理,函式也可以用as指定別名

語法:
from module_name import function_name as fn
fn()
如:
from pizza import make_pizza as mp
mp( 16, 'pepperoni' )

(3)匯入模組中所有函式

  使用星號(*)運算子可讓Python匯入模組中的所有函式

語法:
from module_name import *
function_name()
如:
from pizza import *
make pizza( 16, 'pepperoni' )

  然而,當使用非自己編寫的大型模組時,最好不要採用這種方法。如果模組中有函式名稱和當前程式中相同,可能出現意想不到的結果。所以除非情況特殊,最好使用前兩種匯入方法。

參考書籍:《Python程式設計:從入門到實踐》

2020-07-14