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ù),分別是:parameters和arguments
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_models和show_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