函數(shù)
位置實參
你調(diào)用函數(shù)時,Python必須將函數(shù)調(diào)用中的每個實參都關(guān)聯(lián)到函數(shù)定義中的一個形參。因此最簡單的關(guān)聯(lián)方式是基于實參的順序乡翅。這種關(guān)聯(lián)方式被稱為位置實參鳞疲。
def describe(animal_type,pet_name):
'''顯示寵物的信息‘’‘
print('I have a'+anmial_type + '.' + 'Its name is'+ pet_name)
describe('dog','harry')
位置實參的順序很重要
使用位置實參來調(diào)用函數(shù)時,如果實參的順序不正確蠕蚜,結(jié)果可能出乎意料:
比如再上面的例子中尚洽,我們先指定名字,再指定動物類型describe('harry','dog')
由于實參'harry'
在前靶累,這個值將存儲到形參animal_type
中腺毫;同理,'hamster'將存儲到形參pet_name
中挣柬。結(jié)果時我們得到了一個名字為dog
的harry
:
describe('harry','dog')
>>I have a harry. Its name is dog
關(guān)鍵字實參
關(guān)鍵字實參是傳遞給函數(shù)名稱-值
對潮酒。
直接在實參中將名稱和值關(guān)聯(lián)起來,因此向函數(shù)傳遞實參時不會混淆(不會的得到名為dog的harry這樣的結(jié)果)凛忿。關(guān)鍵字實參讓你無需考慮函數(shù)調(diào)用中的實參順序澈灼,還清楚地指出了函數(shù)調(diào)用中各個值得用途。
下面兩個函數(shù)調(diào)用是等效得:
describe(animal_type = 'dog',pet_name = 'harry')
describe(pet_name = 'harry',animal_type = 'dog')
關(guān)鍵字實參得順序無關(guān)緊要店溢,因為Python知道各個值該存儲到哪個形參中叁熔。
注:使用關(guān)鍵字實參時,務(wù)必準確地指定函數(shù)定義中地形參名
默認值
編寫函數(shù)時床牧,可給每個形參指定默認值荣回。在調(diào)用函數(shù)中給形參提供了實參時,Python將使用指定地實參值戈咳;否則心软,將使用形參的默認值。因此著蛙,給形參指定默認值后删铃,可在函數(shù)調(diào)用中省略相應(yīng)的實參。使用默認值可簡化函數(shù)調(diào)用踏堡,還可清楚地指出函數(shù)地典型用法猎唁。
例如,如果你發(fā)現(xiàn)調(diào)用describe()時顷蟆,描述的大都是小狗诫隅,就可將形參animal_type的默認值設(shè)置為‘dog'。這樣帐偎,調(diào)用describe()來描述小狗時逐纬,就可不提供這種信息:
def describe(pet_name,animal_type = 'dog'):
'''顯示寵物的信息‘’‘
print('I have a'+anmial_type + '.' + 'Its name is'+ pet_name)
這樣調(diào)用這個函數(shù)時削樊,如果沒有給animal_type指定值豁生,Python將把這個形參設(shè)置為’dog‘:
describe(pet_name = 'willie')
>>I have a dog. Its name is willie
請注意,在這個函數(shù)的定義中,修改了形參的排列順序。由于給animal_type指定了默認值沛硅,無需通過實參來指定動物類型眼刃,因此在函數(shù)調(diào)用中只包含一個實參——寵物的名字。然而摇肌,python依然將這個實參視為位置實參,因此如果函數(shù)調(diào)用中只包含寵物的名字仪际,這個實參將關(guān)聯(lián)到函數(shù)定義中的第一個形參围小。這就是需要將pet_name放在形參列表開頭的原因所在。
現(xiàn)在树碱,使用這個函數(shù)的最簡單的方式是肯适,在函數(shù)調(diào)用中只提供小狗的名字:
describe('willie')
這個函數(shù)調(diào)用的輸出與前一個示例相同。只提供了一個實參——'willie'成榜,這個實參將關(guān)聯(lián)到函數(shù)定義中的第一個形參——pet_name框舔。由于沒有給animal_type提供實參,因此Python使用其默認值'dog'赎婚。
注意:使用默認值時刘绣,在形參列表中必須先列出沒有默認值的形參,再列出有默認值的形參挣输。這讓Python依然能夠正確地解讀位置實參纬凤。
讓實參變成可選的
有時候,需要讓實參變成可選的撩嚼,這樣使用函數(shù)的人就只需在必要時才提供額外的信息停士。可使用默認值來讓實參變成可選的完丽。
例如恋技,假如
def get_formatted_name(first_name,middle_name,last_name):
"""返回整潔的姓名"""
full_name = first_name + ' ' + middle_name + last_name
return full_name.title()
只要同時提供名,中間名和姓逻族,這個函數(shù)就能正確地運行蜻底。它根據(jù)這三部分創(chuàng)建一個字符串,在適當?shù)氐胤郊由峡崭翊砂遥⒔Y(jié)果轉(zhuǎn)換為首字母大寫格式
然而朱躺,并非所有地人都有中間名,但如果你調(diào)用這個函數(shù)時只提供了名和姓搁痛,它將不能正確地運行长搀。為讓中間名變成可選地,可給實參middle_name指定一個默認值——空字符串鸡典,并在用戶沒有提供中間名時不使用這個實參源请。為讓get_formatted_name()在沒有提供中間名時依然可行,可給實參middle_name指定一個默認值——空字符串,并將其移到形參列表地末尾:
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()
在這個示例中谁尸,姓名是根據(jù)三個可能提供地部分創(chuàng)建的舅踪。由于人都有名和姓,因此在函數(shù)定義中首先列出了這兩個形參良蛮。中間名是可選的抽碌,因此在函數(shù)定義中最后列出該形參,并將默認值設(shè)置為空字符串决瞳。
傳遞任意數(shù)量的實參
有時候货徙,你預(yù)先不知道函數(shù)需要接受多少個實參,好在Python允許函數(shù)從調(diào)用語句中收集任意數(shù)量的實參皮胡。
例如痴颊,來看看一個制作比薩的函數(shù),它需要接受很多配料屡贺,但你無法預(yù)先確定顧客要多少種配料蠢棱。下面的函數(shù)只有一個形參*toppings,但不管調(diào)用語句提供了多少實參甩栈,這個形參都將它們統(tǒng)統(tǒng)收入囊中:
def make_pizza(*toppings):
"""打印顧客點的所有配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms','green peppers','extra cheese')
形參名*toppings中的星號讓Python創(chuàng)建一個名為topings的空元組泻仙,并收到的所有值都封裝到這個元組中。
不管收到的是一個值還是三個值谤职,這個函數(shù)都能妥善地處理:
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 topings:
- mushrooms
- green pepers
- extra cheese
結(jié)合使用位置實參和任意數(shù)量實參
如果要讓函數(shù)接受不同類型的實參饰豺,必須在函數(shù)定義中將接納任意數(shù)量實參的形參放在最后。PYthon先匹配位置實參和關(guān)鍵字實參允蜈,再將余下的實參都收集到最后一個形參中冤吨。
例如,如果前面的函數(shù)還需要一個表示比薩尺寸的實參饶套,必須將該形參放在形參*toppings的前面:
def make_pizza(size,*toppings):
"""概述要制作的披薩"""
print("\nMaking a " + str(size)+"-ich pizze with the following toppings:")
for toppings in toppings:
print("- " + topping)
making_pizza(16,'pepperoni')
making_pizza(12,'mushrooms','green peppers','extra cheese')
使用任意數(shù)量的關(guān)鍵字實參
有時候漩蟆,需要接受任意數(shù)量的實參,但預(yù)先不知道傳遞給函數(shù)的會是什么樣的信息妓蛮。在這種情況下怠李,可將函數(shù)編寫成能夠接受任意數(shù)量的鍵-值——調(diào)用語句提供了多少就接受多少。
示例:創(chuàng)建用戶簡介
只知道將要收到關(guān)于用戶的信息蛤克,但不確定會是什么樣的信息捺癞。在下面的示例中,函數(shù)build_profile()接受名和姓构挤,同時還接受任意數(shù)量的關(guān)鍵字實參
#user_profile.py
def build_profile(first,last,**user_info)
"""創(chuàng)建一個字典髓介,其中包含我們知道的有關(guān)用戶的一切"""
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)
函數(shù)build_profile()的定義要求提供名和姓,同時允許用戶根據(jù)需要提供任意數(shù)量的名稱-值對筋现。形參**user_info中的兩個星號讓Python創(chuàng)建一個名為user_info的空字典唐础,并將收到的所有名稱-值對都封裝到這個字典中箱歧。在這個函數(shù)中,可以像訪問其他字典那樣訪問user_info中的名稱-值對
將函數(shù)存儲在模塊中
通過將函數(shù)存儲在獨立的文件中一膨,可隱藏程序代碼的細節(jié)呀邢,將重點放在程序的高層邏輯上。這還能讓你在眾多不同的程序中重用函數(shù)豹绪。將函數(shù)存儲在獨立文件后价淌,可與其他程序員共享這些文件而不是整個函數(shù)。知道如何導(dǎo)入函數(shù)還能讓你使用其他程序員編寫的函數(shù)庫
導(dǎo)入整個模塊
要讓函數(shù)是可導(dǎo)入的森篷,得先創(chuàng)建模塊输钩。模塊是擴展名為.py得文件,包含要導(dǎo)入得程序中的代碼仲智。下面來創(chuàng)建一個包含函數(shù)make_pizza()的模塊。
pizza.py
def make_pizza(size,*toppings):
"""概述要制作的披薩"""
print("\nMaking a " + str(size)+"-ich pizze with the following toppings:")
for toppings in toppings:
print("- " + topping)
接下來姻氨,我們只需要在新文件中通過import pizza
即可調(diào)用這個文件里面的函數(shù):
import pizza
pizza.make_pizza(16,'pepperoni')
Python 讀這個文件時钓辆,代碼行import pizza
讓Python打開文件pizza.py,并將其中的所有函數(shù)都復(fù)制到這個程序中肴焊。
導(dǎo)入特定的函數(shù)
from modle_name import function_name
通過用逗號分隔函數(shù)名前联,可根據(jù)需要從模塊中導(dǎo)入任意數(shù)量的函數(shù):
from modle_name import function_nam_e_1,function_name_2
使用as給函數(shù)指定別名
from pizza import make_pizza as mp
使用as給模塊指定別名
impost pizza as p
導(dǎo)入模塊中的所有函數(shù)
使用星號(*)運算符可讓Python導(dǎo)入模塊中的所有函數(shù):
from pizza import *
making_pizza(16,'pepperoni')
making_pizza(12,'mushrooms','green peppers','extra cheese')
import語句中的星號讓python將模塊pizza中的每個函數(shù)都復(fù)制到這個程序文件中。由于導(dǎo)入了每個函數(shù)娶眷,可通過名稱來調(diào)用每個函數(shù)似嗤,而無需使用句點表示法。然而并非自己編寫的大型模塊時届宠,最好不要采用這種導(dǎo)入方法:如果模塊中有函數(shù)的名稱與你的項目中使用的名稱相同烁落,可能導(dǎo)致意想不到的結(jié)果:Python可能遇到多個名稱相同的函數(shù)或變量,進而覆蓋函數(shù)豌注,而不是分別導(dǎo)入所有函數(shù)
最佳的做法是伤塌,要么導(dǎo)入你需要使用的函數(shù),要么導(dǎo)入整個模塊并使用句點表示法轧铁。讓代碼更清晰每聪,更容易閱讀和理解。
函數(shù)編寫指南
應(yīng)給函數(shù)指定描述性名稱齿风,且只在其中使用小寫字母和下劃線药薯。
每個函數(shù)都應(yīng)包含簡要地闡述其功能地注釋,該注釋應(yīng)該緊跟在函數(shù)定義后面救斑。
其他程序員只要知道函數(shù)的名稱童本,需要的實參以及返回值的類型就能在自己的程序中使用它。