函式的意義就是保證和隱藏實現細節,對呼叫者來說,只要知道傳什麼引數和返回什麼值。
python的函式定義非常簡單,但靈活度卻非常大。除了正常定義的必選引數外,還可以使用預設引數、可變引數和關鍵字引數,使得函式定義出來的介面,不但能處理複雜的引數,還可以簡化呼叫者的**。
位置引數非常簡單明白,就是乙個最普通的函式引數形式,比如乙個計算平方的函式:
def
power
(n):
return n * n
這個n
就是乙個位置引數,直接呼叫power(2)
即可。比如我們在定義乙個函式來實現乙個數的任意次方:
def
power
(x, n)
: s =
1while n >0:
n = n -
1 s = s * x
return s
方法中兩個位置引數 x, n,位置引數的意思就是你呼叫時對應的值要放到方法對應的引數的位置上。
對於上面的power
方法,實現第二種以後,原來呼叫第一種的**就會出錯來,怎麼辦呢?當然我們可以修改出錯的**,讓其適應新**,還有一種方法就是給引數n
設定乙個預設值:
def
power
(x, n=2)
:pass
這時我們在呼叫power(5)
就相當於呼叫power(5, 2)
,而對於 n 為其他值的情況還是要明確傳入位置引數,比如:power(5, 3)
。
設定預設引數時,有幾點要注意:
在有多個預設引數時,呼叫時也有一點要注意,比如定義乙個如下方法:
def
register
(name, age=
20, gender=
'male'
, city=
'beijing'):
pass
如果呼叫是,只傳第乙個引數,那後面三個自然使用預設值,如果四個引數全傳,自然也會使用傳入的值來覆蓋預設值,但是如果要中間兩個想使用預設值,最後乙個要傳值怎麼搞?當不按順序提供部分預設引數時,需要把引數名寫上,上面的方法可以這麼呼叫:register('tony', city='london')
,而其他引數仍然使用預設值。
還有個預設引數的小坑,就是預設引數的值不能是可變物件,比如下面的方法:
def
add_end
(l=)
:'end'
)return l
當你連續呼叫並使用預設值時,你會發現結果很詭異:
>>> add_end()
['end']
>>> add_end()
['end', 'end']
原因解釋如下:
python函式在定義的時候,預設引數l的值就被計算出來了,即,因為預設引數l也是乙個變數,它指向物件,每次呼叫該函式,如果改變了l的內容,則下次呼叫時,預設引數的內容就變了,不再是函式定義時的了。
所以要牢記預設引數必須指向不變物件!
要修改上面的例子,我們可以用none這個不變物件來實現:
def
add_end
(l=none):
if l is
none
: l =
'end'
)return l
在python函式中,還可以定義可變引數。顧名思義,可變引數就是傳入的引數個數是可變的,可以是1個、2個到任意個,還可以是0個。
比如我們要計算多個數的求和,定乙個接收多變引數的形式:
def
calc
(*numbers)
:sum=0
for n in numbers:
sum=
sum+ n * n
return
sum
在方法內部,這個numbers
會被解析成乙個tuple
,呼叫時就可以這樣:
>>> calc(1)
1>>> calc(1, 2)
5
如果已經有乙個 list 或者 tuple,要呼叫乙個可變引數怎麼辦?可以這樣做:
>>> nums = [1, 2, 3]
>>> calc(*nums)
14
在 list 或 tuple 前面加乙個*
號,把 list 或 tuple 的元素變成可變引數傳進去。這種寫法非常有用,而且常用。
可變引數允許你傳入0個或任意個引數,這些可變引數在函式呼叫時自動組裝為乙個tuple。而關鍵字引數允許你傳入0個或任意個含引數名的引數,這些關鍵字引數在函式內部自動組裝為乙個dict。示例:
def
person
(name, age,
**kw)
:print
('name:'
, name,
'age:'
, age,
'other:'
, kw)
函式person除了必選引數name和age外,還接受關鍵字引數kw。在呼叫該函式時,可以只傳入必選引數:
>>> person('michael', 30)
name: michael age: 30 other: {}
也可以傳入任意個數的關鍵字引數:
>>> person('bob', 35, city='beijing')
name: bob age: 35 other:
>>> person('adam', 45, gender='m', job='engineer')
name: adam age: 45 other:
和可變引數類似,也可以先組裝出乙個dict,然後,把該dict轉換為關鍵字引數傳進去:
>>> extra =
>>> person('jack', 24, **extra)
name: jack age: 24 other:
**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)
和關鍵字引數 **kw 不同,命名關鍵字引數需要乙個特殊分隔符*
,*
後面的引數被視為命名關鍵字引數。
呼叫方式如下:
>>> person('jack', 24, city='beijing', job='engineer')
jack 24 beijing engineer
如果函式定義中已經有了乙個可變引數,後面跟著的命名關鍵字引數就不再需要乙個特殊分隔符*了:
def
person
(name, age,
*args, city, job)
:print
(name, age, args, city, job)
呼叫時,前面的 name 和 age 是位置引數,必須輸入,後面的 city 和 job 是關鍵字引數,輸入是必須指定關鍵字:
person(
'kaka'
,100
,'單身'
, city=
'上海'
, job=
'銷售'
)
如果後面的 city 或 job 指定來預設值,呼叫時就可以不輸入值了。
對於任意函式,都可以通過類似func(*args, **kw)的形式呼叫它,無論它的引數是如何定義的。
Python學習筆記 Python之函式
1.函式引數函式定義的時候自己定義的引數,稱為形參 函式呼叫時候,其引數為實參,即實際要傳遞的引數 舉例 def pname username username 形參 print username pname python 傳遞了乙個實參 args是接受所有未命名的引數 關鍵字 是乙個元組型別 ag...
Python學習筆記 Python之函式
1.函式引數函式定義時,自己定義的引數,稱為形參 函式呼叫時,其引數為實參,即實際要傳遞的引數 舉例 def pname username username 形參 print username pname python 傳遞了乙個實參 args是接受所有未命名的引數 關鍵字 是乙個元組型別 agrs...
Python學習筆記之函式
python學習過程中重要的知識點函式。1.函式的定義 使用關鍵字 def def sayhello print hello word 以上函式功能只是做了簡單的螢幕輸出 2.函式呼叫 函式定義完之後,需要顯示呼叫才能執行函式體裡的 sayhello 在顯示的呼叫了sayhello 函式的時候,在螢...