lambda表達式返回匿名函數(shù)
- python使用lambda創(chuàng)建匿名函數(shù)旺拉,lambda的主題是一個表達式而不是代碼塊
- 格式:
lambda 參數(shù) : 表達式
肮雨,返回lambda函數(shù)弟断,匿名函數(shù)的返回值即表達式的運算值
a = lambda x, y: x + y # lambda表達式返回匿名函數(shù)殊霞,然后變量a指向此匿名函數(shù)
print(a) # lambda函數(shù): <function <lambda> at 0x000001FE58231E18>
a(1, 2) # 返回:3
# 直接調(diào)用lambda匿名函數(shù)本身
(lambda x, y: x+y)(x=1, y=2) # 返回:3
# lambda作為函數(shù)返回值
def test():
return lambda x, y: x + y
b = test()
print(b) # 函數(shù)類型:<function test.<locals>.<lambda> at 0x000001FE585A5730>
b(1, 2) # 返回:3
高階函數(shù)
- 函數(shù)作為參數(shù)值,應用廣泛顽腾,類似于:f(g(x))
- 函數(shù)作為返回值壁顶,往往形成閉包珠洗,類似于:f(x)(y)
- 關(guān)于閉包:
- 有權(quán)訪問另一個函數(shù)作用域內(nèi)變量的函數(shù)都是閉包。
- 閉包就是 一個函數(shù)引用另一個函數(shù)中的變量若专,因為變量被引用著所以不會被回收(正好印證了垃圾回收機制的引用計數(shù)機制)许蓖。
- 閉包影響的是變量的生命周期,因此可以用于封裝一個私有變量调衰,這是優(yōu)點也是缺點膊爪,缺點就是不必要的閉包只會徒增內(nèi)存消耗。
柯里化函數(shù)
- 柯里化:將原來接受兩個/多個參數(shù)的函數(shù)改為接受一個參數(shù)的函數(shù)嚎莉,該函數(shù)返回嵌套在該函數(shù)里接收所有剩余參數(shù)的函數(shù)米酬。
- 柯里化函數(shù)的運行過程就是參數(shù)的收集過程,我們將每一次傳入的參數(shù)收集起來趋箩,并在最里層的函數(shù)中進行處理赃额。
f(x, y) 轉(zhuǎn)化為 f(x)(y)
def add(x, y):
return x+y
def currying_add(x):
def inner_add(y):
return x+y
return inner_add # 返回內(nèi)嵌的函數(shù)
def currying_add(x):
return lambda y: x+y # 直接使用lambda表達式,返回匿名的函數(shù)
currying_add(4)(5) # 同 add(4, 5)
python裝飾器
- 裝飾器就是一個閉包叫确,為了不影響現(xiàn)有的函數(shù)跳芳,將被裝飾的函數(shù)作為參數(shù)傳遞給一個裝飾器函數(shù),并返回增強后的被裝飾的函數(shù)启妹。
- 帶參裝飾器和無參裝飾器
def logger(fn):
def wrap(*args, **kwargs)
ret = fn(*args, **kwargs) # 閉包,fn函數(shù)沒有被回收醉旦,所以fn就會替換指向add
print('函數(shù)參數(shù)類型:{}饶米,{}'.format(args, wargs))
return ret
return wrap
# 語法糖: 等價于add = logger(add)桨啃,add被包裝函數(shù)替換
@logger
def add(x, y):
return x+y
foo = logger(add) # 內(nèi)嵌wrap函數(shù)
foo(1, 2) # 實參為args,輸出:函數(shù)參數(shù)類型:'(1, 2), {}'檬输,返回:3
foo(x=1, y=2) # 實參為kwargs照瘾,輸出:函數(shù)參數(shù)類型:'(), {x=1, y=2}',返回:3
add = logger(add) # 因為add作為實參傳遞給fn之后丧慈,fn被wrap引用所以fn并沒有銷毀析命,這里的add增強后的函數(shù)
add(1, 2) # 此處的add是增強后的add
- 帶參數(shù)的裝飾器
@router.get("/student2/list", response=List[StudentSchemaOut])
@paginate(MyPagination)
# listStudent = paginate(listStudent)
def listStudent(request, filters: FiltersSchema = Query(...)):
query_set = lists(request, filters, StudentInfo)
return query_set
def paginate(
func_or_pgn_class: Any = NOT_SET, **paginator_params: DictStrAny
) -> Callable:
"""
@api.get(...
@paginage
def my_view(request):
or
@api.get(...
@paginage(PageNumberPagination)
def my_view(request):
"""
isfunction = inspect.isfunction(func_or_pgn_class)
isnotset = func_or_pgn_class == NOT_SET
pagination_class: Type[PaginationBase] = import_string(settings.PAGINATION_CLASS)
if isfunction:
return _inject_pagination(func_or_pgn_class, pagination_class)
if not isnotset:
pagination_class = func_or_pgn_class
def wrapper(func: Callable) -> Any:
return _inject_pagination(func, pagination_class, **paginator_params)
return wrapper
使用functools的wrap實現(xiàn)日志記錄裝飾器
https://blog.csdn.net/weixin_44799217/article/details/118695357
https://blog.csdn.net/lzf9651/article/details/139641445
from functools import wraps
# 添加操作日志裝飾器--不帶參數(shù)的裝飾器
def addLog(fn):
"""
@api.get(...
@addLog
def my_view(request):
"""
@wraps(fn)
def wrapper(*args, **kwargs):
create(data={"operate_module": "aaa"}, model=SkssLog)
return fn(*args, **kwargs)
return wrapper
# 添加操作日志裝飾器---帶參數(shù)的裝飾器
def addLog(comment):
"""
@api.get(...
@addLog("添加日志")
def my_view(request):
"""
def log(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
create(data={"operate_module": comment}, model=SkssLog)
return fn(*args, **kwargs)
return wrapper
return log
@property裝飾器
- python內(nèi)置的
@property
裝飾器就是負責把一個方法變成只讀屬性調(diào)用。
class A(object):
_name = 'testA'
@property
def test(self):
return self._name
@property # 定義對象的讀取getter屬性test2
def test2(self):
return self._age
@test2.setter # 定義對象的寫setter屬性
def test2(self, age):
self._age = age
a = A()
print(a.test) # 把test()方法作為屬性調(diào)用逃默,不用加上小括號鹃愤,返回:'testA'
print(a.test()) # 報錯:TypeError: 'str' object is not callable
a.test2 = 24
print(a.test2) # 返回:24