02 - 函數與裝飾器
函數與裝飾器
函數
概念
函數是組織好的,可重復使用的,用來實現單一,或相關聯功能的代碼段。
函數的返回值
return [表達式] 語句用於退出函數,選擇性地向調用方返回一個表達式。不帶參數值的return語句返回None。
# return a,b,c等價於 return (a,b,c) def test(): a,b = 10,20 return a,b print(test())
不定長參數傳遞
加了星號(*)的變量args會存放所有未命名的變量參數,args為元組;
而加**的變量kwargs會存放命名參數,即形如key=value的參數, kwargs為字典。
def function(a,b,*args,**kwargs):#裝箱 print(a,b) print(args)#元組存放 print(kwargs)#字典存放 A = (33,44,55) B = {"name":"jerry","age":6} function(11,22,*A,**B) #拆包元組和字典
全局變量
在python中,創建變量時默認是定義新的變量(局部變量),除非顯式聲明global。
對於不可變對象(數值,字符串,元祖)的全局變量來說,因其指向的數據不能修改,所以不使用global時無法修改全局變量。
a = 1 def f(): a += 1 # a = a+1,默認局部變量,變量a沒有指向,就被引用計算,故報錯 print(a) f() UnboundLocalError: local variable ‘a‘ referenced before assignment
對於可變對象(比如list和dictionary)的全局變量來說,因其指向的數據可以修改,所以不使用global時也可修改全局變量。
a = [1,2,3] def f(): a.append(4) # 對可變對象的全局變量a的操作,id相同 f()print(a) #結果:[1, 2, 3, 4]
函數傳遞參數類型
函數傳遞參數類型,引用傳遞or值傳遞。
"""對變量賦值時的地址變化""" a = [1,2,3] b = [1,2,3] c = 1 d = 1 print(id(a)) #2190918037640 print(id(b)) #2190920543560 print(id(c)) #1929604576 多個變量會指向同一個地址 print(id(d)) #1929604576
實例1
a = 1 print(id(a)) #1929604576 def function(b): print(id(b)) #1929604576 引用傳遞,指向關系相同 b += 1 #判斷變量b是否可修改,不是則默認執行b = b+1 print(b) #2 print(id(b)) #1929604608 變量b改變指向(不可變對象) function(a) print(a) #1
實例2
a = [1,2,3] a = [1,2,3] def function(b): def function(b): b = b+[4] b += [4] #和b.append(4)結果相同 print(b) print(b) function(a) function(a) print(a) print(a) #結果:[1, 2, 3, 4] 結果:[1, 2, 3, 4] # [1, 2, 3] [1, 2, 3, 4]
總結:賦值相當於變量指向了新的地址(+=除外), 在python中,不可變對象是共享的,創建可變對象永遠是分配新地址。
缺省參數
註意:帶有默認值的參數一定要位於參數列表的最後面。
def test(a,b=12,c=20): pass test(10,c=10) #默認b=12,test(10,12,10)
默認參數的坑
def func(x,l=list()): for i in range(x): l.append(i*2) print(l) func(2) #[0, 2] func(3,[1,2,3]) #[1, 2, 3, 0, 2, 4] func(3) #[0, 2, 0, 2, 4] func(4) #[0, 2, 0, 2, 4, 0, 2, 4, 6] func(3,[1,2,3]) #[1, 2, 3, 0, 2, 4]
匿名函數
語法:變量 = lambda 參數:返回值
ls = lambda x:x+2 print(ls(5)) #結果:7
內置函數:eval()將字符串str當成有效的表達式來求值並返回計算結果。
def test(a,b,fun): return fun(a,b) #匿名函數的調用 lamb = input("請輸入匿名函數:") test(10,20,eval(lamb)) #eval()原樣輸出 #請輸入匿名函數: lambda x,y:x+y #結果:30
匿名函數的應用
# 取出最大工資對應的人名 salaries = { ‘qiu‘: 2000, ‘xi‘: 30000, ‘qiuxi‘: 2500, ‘rufeng‘: 3000 } def func(k): return salaries[k] print(max(salaries,key=func)) # xi # 1. 將可叠代對象salaries變成叠代器對象iter_obj # 2. next(iter_obj)得到一個人名,然後將該人名當作參數傳給key指定的函數,然後調用函數將函數的返回值當作比較依據 # 3. 比較大小,取出最大值對應的人名 # 上面的函數還可以用匿名函數來實現 print(max(salaries, key=lambda k: salaries[k])) # 同樣,取出最小的使用函數min print(min(salaries, key=lambda k: salaries[k]))max與lambda
內置函數:sorted(),排序並返回新的值
a = {k1:v1,k2:v2} # 從大到小 print(sorted(salaries, key=lambda k: a[k], reverse=True)) # 從小到大 print(sorted(salaries, key=lambda k: a[k]))
內置函數:map()提供的函數對指定序列做映射。
map(function, iterable, ...)
name = [a,b,c,d] # 列表生成式 new_names = [name+‘_1‘ for name in names] print(new_names) # map+匿名函數 res = map(lambda x: x+‘_1‘, names) print(res) #打印函數地址 print(list(res))
functools模塊函數 :reduce()對參數序列中元素進行累積。
reduce(function, iterable[, initializer])
from functools import reduce reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函數 #結果:15
內置函數:filter() 函數用於過濾序列,過濾掉不符合條件的元素,返回由符合條件元素組成的新列表。
filter(function, iterable)
a = [1,2,3,4,5,6,7,8] b = filter(lambda x:x%2==0,a) #滿足函數條件的留下,即返回值是True,b為叠代器對象 print(list(b))
02 - 函數與裝飾器