Python3 基礎:定義函式
在Python中,定義一個函式要使用def
語句,依次寫出函式名、括號、括號中的引數和冒號:
,然後,在縮排塊中編寫函式體,函式的返回值用return語句返回
。
如果沒有return語句,函式執行完畢後也會返回結果,只是結果為None。
return None可以簡寫為return。
1.空函式
如果想定義一個什麼事也不做的空函式,可以用pass語句
:
def nop():
pass
pass語句什麼都不做,那有什麼用?實際上pass可以用來作為佔位符,比如現在還沒想好怎麼寫函式的程式碼,就可以先放一個pass,讓程式碼能執行起來。
pass還可以用在其他語句裡,比如:
if age >= 18:
pass
缺少了pass,程式碼執行就會有語法錯誤。
2.引數檢查
def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x >= 0:
return x
else:
return -x
3.返回多個值
import math def move(x, y, step, angle=0): nx = x + step * math.cos(angle) ny = y - step * math.sin(angle) return nx, ny >>> x, y = move(100, 100, 60, math.pi / 6) >>> 151.96152422706632 70.0
其實,Python函式返回的仍然是單一值:
>>> r = move(100, 100, 60, math.pi / 6)
>>> print(r)
(151.96152422706632, 70.0)
原來返回值是一個tuple!但是,在語法上,返回一個tuple可以省略括號,而多個變數可以同時接收一個tuple,按位置賦給對應的值,所以,Python的函式返回多值其實就是返回一個tuple.
4.函式的引數
- 位置引數:就是定義函式的引數
預設引數:在定義時給引數賦一個預設值
# 計算x的n次方 def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s
定義預設引數要牢記一點:預設引數必須指向不變物件![預設引數的坑,請看文章末尾]
可變引數: *numbers, 可變引數允許你傳入0個或任意個引數
def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n return sum # 傳入已經存在的list,使用 *list變數名稱 >>> nums = [1, 2, 3] >>> calc(*nums) 14
在函式內部,引數numbers接收到的是一個tuple.
關鍵字引數:
可變引數允許你傳入0個或任意個引數,這些可變引數在函式呼叫時自動組裝為一個tuple。而關鍵字引數允許你傳入0個或任意個含引數名的引數,這些關鍵字引數在函式內部自動組裝為一個dict。def person(name, age, **kw): print('name:', name, 'age:', age, 'other:', kw) # 呼叫person函式 >>> person('Bob', 35, city='Beijing') name: Bob age: 35 other: {'city': 'Beijing'} >>> person('Adam', 45, gender='M', job='Engineer') name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'} # 現成的dict使用 **dict名稱 >>> extra = {'city': 'Beijing', 'job': 'Engineer'} >>> person('Jack', 24, **extra) name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'} **extra表示把extra這個dict的所有key-value用關鍵字引數傳入到函式的**kw引數,kw將獲得一個dict,注意kw獲得的dict是extra的一份拷貝,對kw的改動不會影響到函式外的extra。
命名關鍵字引數:
如果要限制關鍵字引數的名字,就可以用命名關鍵字引數,例如,只接收city和job作為關鍵字引數。這種方式定義的函式如下:
def person(name, age, *, city, job): print(name, age, city, job)
命名關鍵字引數需要一個特殊分隔符*,*後面的引數被視為命名關鍵字引數。
呼叫方式如下:>>> person('Jack', 24, city='Beijing', job='Engineer') Jack 24 Beijing Engineer
如果函式定義中已經有了一個可變引數,後面跟著的命名關鍵字引數就不再需要一個特殊分隔符*了:
def person(name, age, *args, city, job): print(name, age, args, city, job)
命名關鍵字引數必須傳入引數名,這和位置引數不同。如果沒有傳入引數名,呼叫將報錯.
命名關鍵字引數可以有預設值,從而簡化呼叫:def person(name, age, *, city='Beijing', job): print(name, age, city, job) # 由於命名關鍵字引數city具有預設值,呼叫時,可不傳入city引數: >>> person('Jack', 24, job='Engineer') Jack 24 Beijing Engineer
引數組合:
在Python中定義函式,可以用必選引數、預設引數、可變引數、關鍵字引數和命名關鍵字引數,這5種引數都可以組合使用。但是請注意,引數定義的順序必須是:必選引數、預設引數、可變引數、命名關鍵字引數和關鍵字引數。
預設引數的坑
先定義一個函式,傳入一個list,新增一個END再返回:
def add_end(L=[]):
L.append('END')
return L
這個函式正常呼叫是沒有問題的,但是如果你這樣:
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
為什麼會這樣呢?
Python函式在定義的時候,預設引數L的值就被計算出來了,即[],因為預設引數L也是一個變數,它指向物件[],每次呼叫該函式,如果改變了L的內容,則下次呼叫時,預設引數的內容就變了,不再是函式定義時的[]了。
所以,定義預設引數要牢記一點:預設引數必須指向不變物件!
幾個實用函式
函式 描述
dir([obj]) —顯示物件的屬性,如果沒有提供引數, 則顯示全域性變數的名字
help([obj])— 以一種整齊美觀的形式 顯示物件的文件字串, 如果沒有提供任何引數, 則會進入互動式幫助。
int(obj) —將一個物件轉換為整數
len(obj) —返回物件的長度
open(fn, mode)— 以 mode(‘r’ = 讀, ‘w’= 寫)方式開啟一個檔名為 fn 的檔案
range([[start,]stop[,step])— 返回一個整數列表。起始值為 start, 結束值為 stop - 1; start預設值為 0, step預設值為1。
raw_input(str)— 等待使用者輸入一個字串, 可以提供一個可選的引數 str 用作提示資訊。
str(obj)— 將一個物件轉換為字串
type(obj)— 返回物件的型別(返回值本身是一個type 物件!)