在Python中,定義一個(gè)函數(shù)要使用def語句能曾,依次寫出函數(shù)名度硝、括號(hào)、括號(hào)中的參數(shù)和冒號(hào):寿冕,然后蕊程,在縮進(jìn)塊中編寫函數(shù)體,函數(shù)的返回值用return語句返回蚂斤。
我們以自定義一個(gè)求絕對值的my_abs函數(shù)為例:
def my_abs(x):
if x >= 0:
return x
else:
return -x
請注意存捺,函數(shù)體內(nèi)部的語句在執(zhí)行時(shí),一旦執(zhí)行到return時(shí)曙蒸,函數(shù)就執(zhí)行完畢捌治,并將結(jié)果返回。因此纽窟,函數(shù)內(nèi)部通過條件判斷和循環(huán)可以實(shí)現(xiàn)非常復(fù)雜的邏輯肖油。
如果沒有return語句,函數(shù)執(zhí)行完畢后也會(huì)返回結(jié)果臂港,只是結(jié)果為None森枪。return None可以簡寫為return视搏。
空函數(shù)
如果想定義一個(gè)什么事也不做的空函數(shù),可以用pass語句:
def nop():
pass
pass語句什么都不做县袱,那有什么用浑娜?實(shí)際上pass可以用來作為占位符,比如現(xiàn)在還沒想好怎么寫函數(shù)的代碼式散,就可以先放一個(gè)pass筋遭,讓代碼能運(yùn)行起來。
pass還可以用在其他語句里暴拄,比如:
if age >= 18:
pass
缺少了pass漓滔,代碼運(yùn)行就會(huì)有語法錯(cuò)誤。
參數(shù)檢查
調(diào)用函數(shù)時(shí)乖篷,如果參數(shù)個(gè)數(shù)不對响驴,Python解釋器會(huì)自動(dòng)檢查出來,并拋出TypeError:
>>> my_abs(1, 2)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: my_abs() takes 1 positional argument but 2 were given
但是如果參數(shù)類型不對撕蔼,Python解釋器就無法幫我們檢查豁鲤。試試my_abs和內(nèi)置函數(shù)abs的差別:
>>> my_abs('A')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in my_abs
TypeError: unorderable types: str() >= int()
>>> abs('A')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): 'str'
當(dāng)傳入了不恰當(dāng)?shù)膮?shù)時(shí),內(nèi)置函數(shù)abs會(huì)檢查出參數(shù)錯(cuò)誤罕邀,而我們定義的my_abs沒有參數(shù)檢查畅形,會(huì)導(dǎo)致if語句出錯(cuò),出錯(cuò)信息和abs不一樣诉探。所以日熬,這個(gè)函數(shù)定義不夠完善。讓我們修改一下my_abs的定義肾胯,對參數(shù)類型做檢查竖席,只允許整數(shù)和浮點(diǎn)數(shù)類型的參數(shù)。數(shù)據(jù)類型檢查可以用內(nèi)置函數(shù)isinstance()實(shí)現(xiàn):
def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x >= 0:
return x
else:
return -x
添加了參數(shù)檢查后敬肚,如果傳入錯(cuò)誤的參數(shù)類型毕荐,函數(shù)就可以拋出一個(gè)錯(cuò)誤:
>>> my_abs('A')Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in my_absTypeError: bad operand type
返回多個(gè)值
函數(shù)可以返回多個(gè)值嗎?答案是肯定的艳馒。比如在游戲中經(jīng)常需要從一個(gè)點(diǎn)移動(dòng)到另一個(gè)點(diǎn)憎亚,給出坐標(biāo)、位移和角度弄慰,就可以計(jì)算出新的新的坐標(biāo):
import mathdef
move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
import math語句表示導(dǎo)入math包第美,并允許后續(xù)代碼引用math包里的sin、cos等函數(shù)陆爽。
然后什往,我們就可以同時(shí)獲得返回值:
>>> x, y = move(100, 100, 60, math.pi / 6)
>>> print(x, y)
151.96152422706632 70.0
但其實(shí)這只是一種假象,Python函數(shù)返回的仍然是單一值:
>>> r = move(100, 100, 60, math.pi / 6)
>>> print(r)
(151.96152422706632, 70.0)
原來返回值是一個(gè)tuple慌闭!但是别威,在語法上躯舔,返回一個(gè)tuple可以省略括號(hào),而多個(gè)變量可以同時(shí)接收一個(gè)tuple省古,按位置賦給對應(yīng)的值粥庄,所以,Python的函數(shù)返回多值其實(shí)就是返回一個(gè)tuple衫樊,但寫起來更方便飒赃。