python 裝飾器 函式裝飾器 類裝飾器

2021-09-26 13:58:30 字數 4424 閱讀 3197

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...