日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python 中的闭包、匿名函数、decorator 装饰器与python的偏函数

發布時間:2023/12/19 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 中的闭包、匿名函数、decorator 装饰器与python的偏函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python中的閉包

def calc_sum(lst):def lazy_sum():return sum(lst)return lazy_sum

像這種內層函數引用了外層函數的變量(參數也算變量),然后返回內層函數的情況,稱為閉包(Closure)。在函數內部定義的函數和外部定義的函數是一樣的,只是他們無法被外部訪問。

閉包的特點是返回的函數還引用了外層函數的局部變量,所以,要正確使用閉包,就要確保引用的局部變量在函數返回后不能變。

def count():fs = []for i in range(1, 4):def f(i): # 必須傳入參數,生成局部變量,否則調用外層函數變量可變return lambda: i*i # 返回一個匿名函數,也叫 lambda單行表達式fs.append(f(i))return fs f1, f2, f3 = count() print f1(), f2(), f3()

匿名函數

上述代碼中lambda表達式表示簡單的單行函數,方便定義,并且只在函數內部定義使用。

lambda 表達式必須使用 lambda 關鍵字進行定義。在 lambda 關鍵字之后、冒號左邊的是參數列表,可以沒有參數,也可以有多個參數。如果有多個參數,則需要用逗號隔開,冒號右邊是該 lambda 表達式的返回值。

匿名函數有個限制,就是只能有一個表達式,不寫return,返回值就是該表達式的結果。

函數返回時也可以返回匿名函數,如:

myabs = lambda x: -x if x < 0 else x myabs(-1) # 1

decorator 裝飾器

當需要給原函數 f 增加功能時,不需要直接修改原函數。Python的 decorator 本質上就是一個高階函數,它接收一個函數作為參數,然后,返回一個新函數。

高階函數參考:https://blog.csdn.net/Qianzhen_Sun/article/details/105345949

使用 decorator 時,用Python提供的 @ 語法,這樣可以避免手動編寫 f = decorate(f) 這樣的代碼。徹底屏蔽原函數功能。
舉例:

def log(f):def fn(x):print 'call ' + f.__name__ + '()...'return f(x)return fn@log # 該語法等同于 factorial = log(factorial) def factorial(n):return reduce(lambda x,y: x*y, range(1, n+1)) print factorial(10)""" 打印結果 call factorial()... 3628800 """

要讓 @log 自適應任何參數定義的函數,可以利用 Python 的 *args (可變參數,返回一個 tuple)和 **kw (關鍵字參數,返回一個 dict),保證任意個數的參數總是能正常調用:

def log(f):def fn(*args, **kw):print 'call ' + f.__name__ + '()...'return f(*args, **kw)return fn

編寫帶參數的 decorator:

def log(prefix): # 傳入參數def log_decorator(f):def wrapper(*args, **kw):print '[%s] %s()...' % (prefix, f.__name__)return f(*args, **kw)return wrapperreturn log_decorator@log('DEBUG') def test():pass print test()

上面的調用等同于帶參數的log函數首先返回一個decorator函數,再讓這個decorator函數接收my_func并返回新函數。不利用@,拆開調用形式如下:

log_decorator = log('DEBUG') @log_decorator def test():pass print test()

完善 decorator:

decorator 改變了函數名,還改變了函數的__doc__等其它屬性。如果要讓調用者看不出一個函數經過了@decorator的“改造”,就需要把原函數的一些屬性復制到新函數中:

def log(f):def wrapper(*args, **kw):print 'call...'return f(*args, **kw)wrapper.__name__ = f.__name__ # 原函數信息復制過來wrapper.__doc__ = f.__doc__return wrapper

這樣寫 decorator很不方便,因為我們也很難把原函數的所有必要屬性都一個一個復制到新函數上,所以 Python內置的functools可以用來自動化完成這個“復制”的任務:

import functools def log(f):@functools.wraps(f) # 完成復制任務def wrapper(*args, **kw):print 'call...'return f(*args, **kw)return wrapper

Python 的偏函數

functools.partial可以把一個參數多的函數變成一個參數少的新函數,少的參數需要在創建時指定默認值,這樣,新函數調用的難度就降低了。

自定義轉換2進制函數:

def int2(x, base=2):return int(x, base)

可以通過 functools.partial 函數進行轉化:

import functools int2 = functools.partial(int, base=2) import functools # 自定義忽略大小寫排序 sorted_ignore_case = functools.partial(sorted, key=str.lower) print sorted_ignore_case(['bob', 'about', 'Zoo', 'Credit'])

整理不易,點贊支持!

總結

以上是生活随笔為你收集整理的Python 中的闭包、匿名函数、decorator 装饰器与python的偏函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。