1. 程式人生 > >02 - 函數與裝飾器

02 - 函數與裝飾器

實現 lte 默認參數 aps tool 取出 ide src 表達式

函數與裝飾器

函數

概念

函數是組織好的,可重復使用的,用來實現單一,或相關聯功能的代碼段。

函數的返回值

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 - 函數與裝飾器