7.Python函數(shù)

1.定義一個(gè)函數(shù)

定義一個(gè)函數(shù)需要5個(gè)部分:

  • def告訴Python,用戶在自定義函數(shù)
  • function_name告訴Python要定義的函數(shù)的名字,且取名盡量做到descriptive
  • (parameters)這是形式參數(shù),簡(jiǎn)稱(chēng)形參,接收函數(shù)調(diào)用時(shí),傳過(guò)來(lái)的實(shí)參,不需要傳參時(shí)可省略
  • '''docstring'''不執(zhí)行任何功能,僅用來(lái)說(shuō)明函數(shù)功能,調(diào)用函數(shù)者可以查看該函數(shù)的docstring以了解其功能
  • function_body是函數(shù)的主體,函數(shù)要實(shí)現(xiàn)的功能由它決定

格式:

#函數(shù)定義
def function_name(parameters):  #注意冒號(hào)
    '''docstring''' #注意縮進(jìn)1個(gè)tab
    function_body   #注意縮進(jìn)1個(gè)tab

#函數(shù)調(diào)用   
function_name(arguments)    #arguments為實(shí)參,字符串參數(shù)要加引號(hào)

2.參數(shù)

在上述的函數(shù)定義格式中,有兩種參數(shù),分別是:parametersarguments

parameters為形式參數(shù),簡(jiǎn)稱(chēng)為形參在函數(shù)定義時(shí),僅作為符號(hào),表示這里應(yīng)該有這樣一個(gè)參數(shù),實(shí)現(xiàn)函數(shù)的成功定義。

arguments實(shí)參,即主程序中,需要調(diào)用函數(shù)處理的實(shí)實(shí)在在的信息。調(diào)用時(shí),會(huì)實(shí)現(xiàn)parameter_1=argument_1...,將所有實(shí)參的值賦給對(duì)應(yīng)的形參,交由函數(shù)處理。

例:

輸入:

def greet_user(username):
    '''display a simple greeting'''
    print('hello, '+username.title()+'!')
    
greet_user('jack')

輸出:

c:\py>function_define
hello, Jack!

3.傳送多個(gè)參數(shù)

上面的例子是僅傳一個(gè)參數(shù)的情況,parameters和arguments可以有多個(gè),有3種方法實(shí)現(xiàn)多參數(shù)傳送。

(1) 位置實(shí)參

def語(yǔ)句

def function_name(parameter_1, parameter_2,..., parameter_n):

調(diào)用函數(shù)語(yǔ)句

function_name(argument_1, argument_2,..., argument_n):

調(diào)用函數(shù)語(yǔ)句中的實(shí)參與def語(yǔ)句中的形參按順序一一對(duì)應(yīng),傳參時(shí)實(shí)現(xiàn)的操作如下:

parameter_1=argument_1
parameter_2=argument_2
.
.
.
parameter_n=argument_n

注意,使用位置實(shí)參時(shí),一定要按照定義函數(shù)時(shí),正確的順序排列,不然會(huì)出錯(cuò)。

(2) 關(guān)鍵字實(shí)參

關(guān)鍵字傳參是將一個(gè)name-value組合傳給函數(shù)形參。

調(diào)用形式:
function_name(name_1=value_1,name_2=value_2,...,name_n=value_n)

name-value里面,name為函數(shù)定義時(shí),形參的名字,value為主程序中實(shí)參的值,通過(guò)name=value實(shí)現(xiàn)傳參。所以通過(guò)關(guān)鍵字實(shí)參傳參,并不需要按照定義時(shí)的順序。

輸入:

def describe_pet(animal_type,pet_name):
    '''display information about a pet'''
    print('\nI have a '+animal_type+'.')
    print('My '+animal_type+"'s name is "+pet_name+'.')

describe_pet(animal_type='dog',pet_name='harry')
#順序不一樣
describe_pet(pet_name='harry',animal_type='dog')

輸出:

c:\py>describe_pet.py

I have a dog.
My dog's name is harry.

I have a dog.
My dog's name is harry.

上面程序調(diào)用了兩次describe_pet函數(shù),參數(shù)順序不一樣,但是輸出結(jié)果一樣。

(3) 默認(rèn)值

當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),它的某些參數(shù)總是很少改變時(shí),我們可以給這些很少變動(dòng)的參數(shù),在定義函數(shù)時(shí),給它們一個(gè)默認(rèn)值。這樣在調(diào)用函數(shù)時(shí),若與默認(rèn)值相同,則可以不用寫(xiě)該參數(shù)的實(shí)參值,直接采用默認(rèn)值,如果與默認(rèn)值不符,可以用關(guān)鍵字name-value對(duì)傳參。

輸入:

def describe_pet(pet_name,animal_type='dog'):       #默認(rèn)animal_type參數(shù)值為‘dog’
    '''display information about a pet'''
    print('\nI have a '+animal_type+'.')
    print('My '+animal_type+"'s name is "+pet_name+'.')

describe_pet(pet_name='harry')  #省略animal_type參數(shù)值
describe_pet('harry')   #采用位置實(shí)參傳參

describe_pet(animal_type='cat',pet_name='tom') #與默認(rèn)值不符,用name-value對(duì)傳參

輸出:

c:\py>describe_pet.py

I have a dog.
My dog's name is harry.

I have a dog.
My dog's name is harry.

I have a cat.
My cat's name is tom.

注意: 所有帶有默認(rèn)值的參數(shù)必須放在沒(méi)有默認(rèn)值的參數(shù)后面,不然程序會(huì)報(bào)錯(cuò)。

錯(cuò)誤示例:

def describe_pet(animal_type='dog',pet_name):   

輸出:

c:\py>describe_pet.py
  File "C:\py\describe_pet.py", line 1
    def describe_pet(animal_type='dog',pet_name):  

把帶默認(rèn)值的參數(shù)放最后,這樣也可以使用位置實(shí)參來(lái)傳送參數(shù),忽略后面有默認(rèn)值的形參,剩下的與調(diào)用語(yǔ)句中的實(shí)參一一對(duì)應(yīng)。

(4) 可選實(shí)參

我們可以在定義函數(shù)時(shí),把可選參數(shù)的默認(rèn)值設(shè)為空,optional argument='',這樣在調(diào)用函數(shù)時(shí),即使沒(méi)有對(duì)應(yīng)的實(shí)參,也不會(huì)因?yàn)閷?shí)參與形參數(shù)量不匹配而報(bào)錯(cuò)。

輸入:

def get_formatted_name(first_name,last_name,middle_name=''):        #給middle_name賦值為空
    '''return a full name,neatly formatted.'''
    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('jimmi','fallon')
print(musician)
    
musician = get_formatted_name('jimmi','fallon','lee')   #lee放最后,與middle_name相對(duì)應(yīng)
print(musician)

輸出:

c:\py>get_formatted_name2
Jimmi Fallon
Jimmi Lee Fallon

注意: 上例中的middle_name的默認(rèn)值為空字符串,因?yàn)橛心J(rèn)值,要把它放到最后。Python認(rèn)為空字符串的值為0,所以if檢測(cè)到空字符串,即if=0,條件不成立,if下面縮進(jìn)的語(yǔ)句不執(zhí)行,轉(zhuǎn)而執(zhí)行else下面縮進(jìn)的語(yǔ)句。

4.返回值

Python可以返回任意類(lèi)型的值。

(1) 返回簡(jiǎn)單值

我們調(diào)用函數(shù)后,在函數(shù)末尾使用return語(yǔ)句,可以返回被調(diào)用的函數(shù)中需要的值;在主程序中,可以使用一個(gè)賦值語(yǔ)句接收返回值。

輸入:

def get_formatted_name(first_name,last_name):
    '''return a full name, neatly formatted.'''
    full_name = first_name+' '+last_name
    return full_name.title()
musician = get_formatted_name('jimmy','logan') #用musician來(lái)接收返回值
print(musician)

輸出:

c:\py>get_formatted_name.py
Jimmy Logan

(2) 返回字典

輸入:

def get_formatted_name(first_name,last_name):
    '''return a dictionary of information about a person.'''
    person={'first':first_name , 'last':last_name}
    return person
    
musician = get_formatted_name('jimmy','logan')
print(musician)

輸出:

c:\py>get_formatted_name.py
{'first': 'jimmy', 'last': 'logan'}

5.處理列表

(1) 傳遞列表

可以將一部分列表處理流程分離出來(lái),作為函數(shù),此時(shí),函數(shù)中的形參應(yīng)該是一個(gè)列表,在函數(shù)中,也作為一個(gè)列表進(jìn)行處理。在主程序中,傳送的實(shí)參也必須是一個(gè)列表。

輸入:

def greet_users(names): 
    '''Print a simple greeting to each user in the list.'''
    for name in names:
        msg = 'hello, '+name.title()+'!'
        print(msg)

usernames=['jack','tom','lucy']
greet_users(usernames)

輸出:

c:\py>greet_users
hello, Jack!
hello, Tom!
hello, Lucy!

(2) 調(diào)整列表

調(diào)用函數(shù)處理列表,給列表帶來(lái)的變化是永久的。

沒(méi)有使用函數(shù)的程序:

#Start with some designs that need to be printed.
unprinted_designs = ['iphone case' , 'robot pendant' , 'dodecahedron']
completed_models = []

#Simulate printing each design, until none are left.
#Move each design to completed_models after printing.
while unprinted_designs:
    current_design=unprinted_designs.pop()
    #Simulate creating a 3D print from the design.
    print('printing model: '+current_design)
    completed_models.append(current_design)

#Display all completed models.
print("\nThe following models have been printed : ")
for completed_model in completed_models:
    print(completed_model)

輸出:

c:\py>print_model
printing model: dodecahedron
printing model: robot pendant
printing model: iphone case

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

我們可以把print_modelsshow_completed_models作為兩個(gè)函數(shù)封裝起來(lái)。

使用函數(shù)的程序:

def  print_models(unprinted_designs,completed_models):
#Simulate printing each design, until none are left.
#Move each design to completed_models after printing.
    while unprinted_designs:
        current_design=unprinted_designs.pop()
        #Simulate creating a 3D print from the design.
        print('printing model: '+current_design)
        completed_models.append(current_design)

def show_completed_models(completed_models):
#Display all completed models.
    print("\nThe following models have been printed : ")
    for completed_model in completed_models:
        print(completed_model)
        
#Start with some designs that need to be printed.
unprinted_designs = ['iphone case' , 'robot pendant' , 'dodecahedron']
completed_models = []

print("\nunprinted_designs : "+str(unprinted_designs)+'\n')
print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)
print("\ncompleted_models : "+str(completed_models))

輸出:

c:\py>print_model

unprinted_designs : ['iphone case', 'robot pendant', 'dodecahedron']

printing model: dodecahedron
printing model: robot pendant
printing model: iphone case

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

completed_models : ['dodecahedron', 'robot pendant', 'iphone case']

注意: 調(diào)用函數(shù)處理列表,給列表帶來(lái)的變化是永久的,就算函數(shù)里的形參列表名與主程序中的實(shí)參列表名不一致,實(shí)參列表依然與形參列表同步變化。

(3) 用切片使函數(shù)不改變列表

function_name(list_name[:])

list_name[:]將列表復(fù)制一份,作為參數(shù)傳給函數(shù),所有的操作只會(huì)改變切片,不會(huì)改變列表本身。

上例中如果我們不想改變unprinted_designs[:]列表,我們可以用下面的語(yǔ)句來(lái)調(diào)用函數(shù)。

print_models(unprinted_designs[:],completed_models)

6.特殊的傳參情況

(1) 傳遞任意數(shù)量參數(shù)

def function_name( *parameters )

在定義函數(shù)時(shí),給形參名字前面加上一個(gè)‘ * ’號(hào),這時(shí),python會(huì)建立一個(gè)與形參名同名的元組,將調(diào)用函數(shù)時(shí)傳過(guò)來(lái)的實(shí)參,統(tǒng)統(tǒng)保存到元組中。

輸入:

def make_pizza(*toppings):
    '''print the list of toppings that have been requested.'''
    print(toppings)

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

輸出:

c:\py>make_pizza
('pepperoni',)
('mushrooms', 'green peppers', 'extra cheese')

(2) 同時(shí)傳送位置實(shí)參與任意數(shù)量實(shí)參

和帶默認(rèn)值的形參一樣,接收任意數(shù)量實(shí)參的參數(shù)放在位置參數(shù)后面。

輸入:

def make_pizza(size,*toppings):
    '''summarize the pizza we are about to make.'''
    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')

輸出:

c:\py>make_pizza

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) 同時(shí)傳送位置實(shí)參和任意數(shù)量關(guān)鍵字實(shí)參

只在傳送不定數(shù)量的關(guān)鍵字實(shí)參時(shí)使用。

def function_name( **parameters )

在定義函數(shù)時(shí),給形參名字前面加上一個(gè)‘ ** ’號(hào),這時(shí),python會(huì)建立一個(gè)與形參名同名的字典,將調(diào)用函數(shù)時(shí)傳過(guò)來(lái)的實(shí)參nam-value對(duì),以name作為鍵,以value作為值,保存到字典中。

用“ ** ”表示任意數(shù)量關(guān)鍵字參數(shù),并將任意數(shù)量關(guān)鍵字實(shí)參放在最后

輸入:

def build_profile(first,last,**user_info):
    '''build a dictionary containing everything we know about a user.'''
    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='princeton',
                                                field='physics')
print(user_profile)

輸出:

c:\py>build_profile
{'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}

7.while語(yǔ)句和函數(shù)

輸入:

def get_formatted_name(first_name,last_name):
    '''return full name'''
    person=first_name+' '+last_name
    return person

while True:
    print('\nplease tell me your name:')
    print("(enter 'q' to quit)")
    f_name=input('First_name : ')
    if f_name == 'q':       #輸入q退出程序
        break
    l_name=input('Last_name : ')
    if l_name == 'q':
        break
    formatted_name = get_formatted_name(f_name,l_name)
    print("Full_name : "+formatted_name)

輸出:

c:\py>get_formatted_name

please tell me your name:
(enter 'q' to quit)
First_name : jimmy
Last_name : logan
Full_name : jimmy logan

please tell me your name:
(enter 'q' to quit)
First_name : tao
Last_name : ming
Full_name : tao ming

please tell me your name:
(enter 'q' to quit)
First_name :

使用while,我們可以循環(huán)調(diào)用函數(shù)。

8.模塊

將函數(shù)存儲(chǔ)在不同的文件中,可以讓我們忽略程序執(zhí)行的一些細(xì)節(jié),只關(guān)注更高的邏輯。

原程序:

def make_pizza(size,*toppings):
    '''summarize the pizza we are about to make.'''
    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')

將函數(shù)make_pizza作為模塊獨(dú)立出來(lái)。

如下:

def make_pizza(size,*toppings):
    '''summarize the pizza we are about to make.'''
    print('\nmaking a '+str(size)+'-inch pizza with the following toppings')
    for topping in toppings:
        print('- '+topping)

將主程序文件和模塊文件放在同一個(gè)目錄下。

(1) 用import導(dǎo)入整個(gè)模塊

格式: import module_name

主程序:

import pizza        #導(dǎo)入整個(gè)pizza模塊

pizza.make_pizza(16,'pepperoni')  #
pizza.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

import pizza語(yǔ)句會(huì)讓Python將pizza模塊中所有代碼復(fù)制到主程序開(kāi)頭,使主程序可以使用pizza模塊中,所有的函數(shù)。

注意: 直接導(dǎo)入整個(gè)模塊,調(diào)用pizza模塊中的函數(shù)時(shí),需要用一個(gè)‘ . ’將模塊名和函數(shù)名間隔開(kāi),格式如下:

module_name.function_name()

(2)導(dǎo)入特定的函數(shù)

格式:from module_name import function_name

此時(shí)調(diào)用函數(shù)時(shí)不需要‘ . ’來(lái)隔開(kāi)模塊名與函數(shù)名。

輸入:

from pizza import make_pizza        #只導(dǎo)入pizza模塊中的make_pizza函數(shù)

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

輸出與上面的例子相同。

注意: 由于此時(shí)只導(dǎo)入特定的函數(shù),所以主程序調(diào)用時(shí),不加‘.’號(hào)來(lái)表示模塊中的某個(gè)函數(shù)。

(3) 使用as給函數(shù)起別名

如果導(dǎo)入的函數(shù)的名字與主程序中的函數(shù)名沖突,又或者導(dǎo)入的函數(shù)名太長(zhǎng),我們可以用關(guān)鍵字as給函數(shù)起個(gè)別名,主程序可以用別名調(diào)用函數(shù)。

格式:from module_name import function_name as alias

輸入:

from pizza import make_pizza as mp  #給make_pizza函數(shù)起別名為mp

mp(16,'pepperoni')      #使用mp調(diào)用函數(shù)
mp(12,'mushrooms','green peppers','extra cheese')

其輸出與上例相同。

(4) 使用as給模塊起別名

格式:import module_name as alias

輸入:

import pizza as p   #給pizza模塊起別名為p

p.make_pizza(16,'pepperoni')        #使用mp調(diào)用函數(shù)
p.make_pizza(12,'mushrooms','green peppers','extra cheese')

輸出與上例相同。

給模塊起簡(jiǎn)單的別名,可以簡(jiǎn)化程序,讓程序作者將注意力放在描述性強(qiáng)的函數(shù)名上。

注意: 這種方法起別名,調(diào)用函數(shù)時(shí)。依然要用‘ . ’將別名與函數(shù)名分開(kāi)。

(5) 導(dǎo)入模塊中所有的函數(shù)(不推薦)

格式:from pizza imporet *

輸入:

from pizza  import *    #導(dǎo)入所有pizza模塊中的函數(shù)

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

輸出與上例相同。

導(dǎo)入模塊中所有的函數(shù)后,我們調(diào)用函數(shù),就不需要寫(xiě)模塊名和‘ . ’,直接使用函數(shù)名,但是,如果模塊中有和主程序函數(shù)名沖突的,往往會(huì)造成不可預(yù)料的錯(cuò)誤。所以不推薦這種導(dǎo)入方法。

9.函數(shù)編寫(xiě)風(fēng)格

(1) 函數(shù)的參數(shù)賦值,‘=’號(hào)兩邊不留空格

默認(rèn)值: def function_name(parameter_0,parameter_1='default value')

關(guān)鍵字實(shí)參: function_name(value_0,parameter_1='value_1')

(2) 參數(shù)字符超過(guò)79個(gè)

當(dāng)參數(shù)過(guò)多時(shí),我們可以將參數(shù)拆成多行。

格式:

def function_name(
        parameter_0,parameter_1,parameter_2,        #前面兩個(gè)tab
        parameter_3,parameter_4,parameter_5):       #前面兩個(gè)tab
    function body       #前面一個(gè)tab
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容