python函式裝飾器和類裝飾器筆記.
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""@author:ivan
@file: decorators.py
@version:
"""from functools import wraps
# 裝飾器: 目的是為了給函式新增附加功能
# 1. 不帶引數裝飾器
# 此方式, 將會把被裝飾的函式物件作為第乙個引數(形參)傳入裝飾函式中,
# 被裝飾的函式的args和kwargs引數將會自動傳入裝飾器裡面的函式中
def de1(func):
def wrap(*args, **kwargs):
print('func name: ', func.__name__)
print('args: ', args)
print('kargs: ', kwargs)
return func(*args, **kwargs)
return wrap
@de1
def f1(a, b=3):
print(a)
f1(33, b=33)
# 輸出結果
# func name: f1
# args: (33,)
# kargs:
# 33
# f1(33, b=33)執行過程為
# --->>>> 注意: 不是 de1(f1(33, b=33)), 因為裝飾器是把被裝飾的函式作為引數傳給裝飾器, 最後返回來的是乙個函式
# de1(f1)(33, b=33)
# 2. 帶引數的函式裝飾器
def de2(*args, **kwargs):
# 不使用裝飾器引數
print(f'args: ')
print(f'kwargs: ')
def decorator(func):
def wrap(*fargs, **fkwargs):
print('func name: ', func.__name__)
print('fargs: ', fargs)
print('fkwargs: ', fkwargs)
return func(*fargs, **fkwargs)
return wrap
return decorator
@de2(33, a=44)
def f2(a, b=55):
"""f2
"""print(f': ')
f2(123, b=33222)
# 裝飾器會導致被裝飾的函式的元資訊丟失, 如果要保持, 可以使用裝飾器wraps, 見下例子
print(f2.__name__) # 輸出 wrap
print(f2.__doc__) # 輸出 none
# 輸出結果
# args: (33,)
# kwargs:
# func name: f2
# fargs: (123,)
# fkwargs:
# 123: 33222
# 執行過程
# 不是de2(33, a=44)(f2(123, b=33222))
# de2(33, a=44)(f2)(123, b=33222)
def de2(*args, **kwargs):
# 不使用裝飾器引數
print(f'args: ')
print(f'kwargs: ')
def decorator(func):
# 使用wraps可以保持被裝飾函式的元資訊
@wraps(func)
def wrap(*fargs, **fkwargs):
print('func name: ', func.__name__)
print('fargs: ', fargs)
print('fkwargs: ', fkwargs)
return func(*fargs, **fkwargs)
return wrap
return decorator
@de2(33, a=44)
def f2(a, b=55):
"""f2
"""print(f': ')
f2(123, b=33222)
print(f2.__name__) # 輸出 f2
print(f2.__doc__) # 輸出 f2
def de22(*args, **kwargs):
# 使用裝飾器引數
print(f'args: ')
print(f'kwargs: ')
f = 343
def decorator(func):
def wrap(*fargs, **fkwargs):
# 可以直接引用,例如print(args), 但是使用nonlocal宣告後, 才能對args, f進行賦值操作
nonlocal args, f
print(f'args: ')
b = kwargs.get('b')
b = b + 33
kwargs['b'] = b
args = 44
f = 33
print(f'kwargs: ')
print('func name: ', func.__name__)
print('fargs: ', fargs)
print('fkwargs: ', fkwargs)
return func(*fargs, **fkwargs)
return wrap
return decorator
@de22(33, b=3)
def f22(a, b=55):
print(f': ')
f22(123, b=33222)
# 輸出結果
# args: (33,)
# kwargs:
# args: (33,)
# kwargs:
# func name: f22
# fargs: (123,)
# fkwargs:
# 123: 33222
def de3(a):
# 可以看作是de2的簡單版本, 可以直接這樣寫
def decorater(func):
return func
return decorater
@de3(33)
def f3(a, b=33):
print(f'-')
f3(11, b=333)
# 輸出結果
# 11-333
# 執行過程
# de3(33)(f3)(11, b=333)
# 類裝飾器
# 1.不帶引數類裝飾器
class foo(object):
def __init__(self, func):
self._func = func
def __call__(self, *args, **kwargs):
print(f'func name: ')
self._func()
@foo
def f5():
print(334)
f5()
# 輸出
# func name: # 334
# 執行過程
# foo(f5)()
# 2.帶引數的類裝飾器
class foo2(object):
def __init__(self, *args, **kwargs):
# 接收foo2(123, b=44)裡面的引數
self.args = args
self.kwargs = kwargs
# def __call__(self, func):
# # 狸貓換太子, 更換被裝飾的函式
# def f(*args, **kwargs):
# print(args)
# return f
def __call__(self, func):
def wraps(*args, **kwargs):
# 接收f6(1234, d=777)裡面的引數
return func(*args, **kwargs)
return wraps
@foo2(123, b=44)
def f6(c, d=33):
print(f':')
f6(1234, d=777)
# 執行過程
# foo2(123, b=44)(f6)(1234, d=777)
python裝飾器 函式裝飾器,類裝飾器
只要實現此 模式,這個obj就叫乙個裝飾器 參考 函式裝飾器 例子 def decorator func def inner args,kwargs print before.res func args,kwargs print after.return res return inner decor...
函式裝飾器 類裝飾器
一 函式裝飾函式 defwrapfun func definner a,b print function name func.name r func a,b return r return inner wrapfun defmyadd a,b return a b print myadd 2,3 二...
python裝飾器 裝飾器工廠函式
使用裝飾器實現如下所示的列印 小白聯盟def printequel func1 def inner1 print 15 func1 return inner1 def printstar func2 def inner2 print 15 func2 return inner2 printequel...