Python3 CookBook|函數(一)

1、可接受任意數量參數的函數

【問題】
你想構造一個可接受任意數量參數的函數

【就決方案】
爲了能使一個函數接受任意數量的位置參數,可以使用一個 * 參數

def avg(first,*rest)
	return (first + sum(rest)) / (1 + len(rest))

avg(1,2)
avg(1,2,3,4)

爲了接受任意數量的關鍵字參數,使用一個以 ** 開頭的參數。

def a(x,*args,y):
	pass

def b(x, *args,y,**kwargs):
	pass

2、只接受關鍵字參數的函數

【問題】
你希望函數的某些參數強制使用關鍵字參數傳遞

【解決方案】
將強制關鍵字參數放到某個*參數或者單個星後面就能達到這種效果

def recv(maxsize,*,block):
	...
	pass

recv(1024,True) #TypeError
recv(1024,block=True) #ok

利用這種技術,我們還能在接受任意多個位置參數的函數中指定關鍵字參數,比如:

def mininum(*values,clip=None):
	m = min(values)
	if clip is not None:
		m = clip if clip > m else m
	return m

mininum(1,5,2,-5,10) # returns -5
mininum(1,5,2,-5,10,clip=0) # returns 0

3、給函數參數增加元信息

【問題】
你寫好一個函數,然後想爲這個函數的參數增加一些額外信息,這樣的話其他使用者就能清楚的知道這個函數應該怎麼使用。

【解決方案】
使用函數參數註解是一個很好的辦法,它能提示程序員應該怎樣正確使用這個函數。例如,下面有一個被註解了的函數

def add(x:int, y:int) -> int:
	return x + y

4、定義匿名或內聯函數

【問題】
你想爲 sort()操作創建一個很短的回調函數,但又不想用 def 去寫一個單行函數,而是希望通過否個快捷方式以內聯方式來創建這個函數

【解決方案】
當一個函數很簡單,僅僅是計算一個表達式的值的時候,就可以使用 lambda 表達式來代替。

add = lambda x,y:x+y
add(2,3)

def add(x,y):
	return x + y

上面這兩種方式效果是一樣的

5、匿名函數捕獲變量值

【問題】
你用lambda定義一個匿名函數,並想在定義時捕獲到某些變量的值

【解決方案】
我們先看看代碼的效果

x = 10
a = lambda y:x + y
x = 20
b = lambda y:x + y

現在我問你,a(10)和b(10)返回什麼結果?如果你認爲是20和30,那你就錯了 。

a(10)
30

b(10)
30

這次中的奧祕就在於 lambda表達式中 x 是一個自由變量,在運行時綁定值,而不是定義的時候綁定值,這跟函數的默認參數定義是不同的。因此在調用lambda時,x是執行時的值。

如果想讓某個匿名函數在定義的時候就捕獲到值,可以將那個參數值設定爲默認參數,就像下面這樣

x = 10
a = lambda y,x=x,x+y
x = 20
b = lambda y,x=x,x+y

a(10)
# 20
b(10)
# 30

通過一個循環或列表推導中創建一個lambda表達式列表,並期望函數在定義時就記住每次的迭代值。

funcs=[lambda x:x+n for n in range(5)]
	for f in funcs:
		print(f(0))
#4
#4
#4
#4
#4
funs=[lambda x,n=n:x+n for n in range(5)]
	for f in funcs:
		print(f(0))
#0
#1
#2
#3
#4

通過使用函數默認值形式參數,lambda函數在定義時就能綁定值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章