Python4.3

定義函數

在Python中,定義一個函數要使用def語句,依次寫出函數名、括號、括號中的參數和冒號:,然後,在縮進塊中編寫函數體,函數的返回值用return語句返回。
自定義一個求絕對值的my_abs函數:

def my_abs(x):
if x>=0:
    return x
elsereturn –x
print(my_abs(-99))

注意,函數體內部的語句在執行時,一旦執行到return時,函數就執行完畢,並將結果返回。因此,函數內部通過條件判斷和循環可以實現非常複雜的邏輯。
如果沒有return語句,函數執行完畢後也會返回結果,只是結果爲None。return None可以簡寫爲return。
在Python交互環境中定義函數時,注意Python會出現…的提示。函數定義結束後需要按兩次回車重新回到>>>提示符下:

>>> def my_abs(x):
...     if x>=0:
...         return x
...     else:return -x
...
>>> my_abs(-99)
99

如果已經把my_abs()的函數定義保存爲hello.py文件了,那麼,可以在該文件的當前目錄下啓動Python解釋器,用from hello import my_abs導入my_abs()函數,注意hello是文件名(不含.py擴展名):

>>> from hello import my_abs
>>> my_abs(-99)
99

空函數

定義一個什麼事也不做的空函數,可以用pass語句:

def nop():
    pass

pass語句什麼都不做,那有什麼用?實際上pass可以用來作爲佔位符,比如現在還沒想好怎麼寫函數的代碼,就可以先放一個pass,讓代碼能運行起來。
pass還可以用在其他語句裏,比如:

if age >= 18:
    pass

缺少了pass,代碼運行就會有語法錯誤。

參數檢查

調用函數時,如果參數個數不對,Python解釋器會自動檢查出來,並拋出TypeError:

>>> abs(1,2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (2 given)

如果參數類型不對,Python解釋器就無法幫我們檢查。看看my_abs和內置函數abs的差別:

>>> abs('a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): 'str'

>>> from hello import my_abs
>>> my_abs('a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "F:\hello.py", line 2, in my_abs
    if x>0:
TypeError: '>' not supported between instances of 'str' and 'int'

當傳入了不恰當的參數時,內置函數abs會檢查出參數錯誤,而我們定義的my_abs沒有參數檢查,會導致if語句出錯,出錯信息和abs不一樣。所以,這個函數定義不夠完善。
我們修改一下my_abs的定義,對參數類型做檢查,只允許整數和浮點數類型的參數。數據類型檢查用內置函數isinstance()實現,isinstance() 函數用來判斷一個對象是否是一個已知的類型,語法:isinstance(object, classinfo)

def my_abs(x):
    if not isinstance(x,(float,int)):
        raise TypeError('bad operand type')
    if x>0:
        return x
else:return –x

添加了參數檢查後,如果傳入錯誤的參數類型,函數就可以拋出一個錯誤,錯誤和異常處理在後續講到。

返回多個值

函數可以返回多個值。
比如在遊戲中經常需要從一個點移動到另一個點,給出座標、位移和角度,就可以計算出新的新的座標, 然後,我們就可以同時獲得返回值:

>>> import math     #導入math包,並允許後續代碼引用math包裏的sin、cos函數

>>> def  move(x,y,s,angle=0):
...     nx=x+s*math.cos(angle)
...     ny=y-s*math.sin(angle)
...     return nx,ny
...
>>> x,y=move(100,100,60,math.pi/6)
>>> print(x,y)
151.96152422706632 70.0

但其實這只是一種假象,Python函數返回的仍然是單一值:

>>> r = move(100, 100, 60, math.pi / 6)
>>> print(r)
(151.96152422706632, 70.0)

原來返回值是一個tuple!但是,在語法上,返回一個tuple可以省略括號,而多個變量可以同時接收一個tuple,按位置賦給對應的值,所以,Python的函數返回多值其實就是返回一個tuple,但寫起來更方便。

小結

定義函數時,需要確定函數名和參數個數;
如果有必要,可以先對參數的數據類型做檢查;
函數體內部可以用return隨時返回函數結果;
函數執行完畢也沒有return語句時,自動return None。
函數可以同時返回多個值,但其實就是一個tuple。

練習

請定義一個函數quadratic(a, b, c),接收3個參數,返回一元二次方程:
ax2 + bx + c = 0的兩個解。提示:計算平方根可以調用math.sqrt()函數:

# -*- coding: utf-8 -*-
import math
def quadratic(a,b,c):
    if b*b-4*a*c>=0:
        d=math.sqrt(b*b-4*a*c)
        x1=(b+d)/(-2*a)
        x2=(b-d)/(-2*a)
        return x1,x2
    else:print('無解')

測試:

>>> from hello import quadratic
>>> print('quadratic(2,3,1)=',quadratic(2,3,1))
quadratic(2,3,1)= (-1.0, -0.5)
>>> print('quadratic(1, 3, -4) =', quadratic(1, 3, -4))
quadratic(1, 3, -4) = (-4.0, 1.0)
>>> if quadratic(2,3,1)!= (-1.0, -0.5):
...     print('ceshishibai')
... elif quadratic(1, 3, -4)!= (-4.0, 1.0):
...     print('shibai')
... else:print('chenggong')
...
chenggong
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章