如何定義帶引數裝飾器?

2022-06-22 11:57:11 字數 1913 閱讀 1664

需求:

實現乙個裝飾器,它用來檢查被裝飾函式的引數型別,裝飾器可以通過引數來指明函式引數型別,呼叫時如果檢測出引數不匹配則丟擲異常

@type_assert(str,int,int)

def f(a,b,c):

....

@type_assert(y=list)

def g(x,y):

....

思路:1、提取函式簽名,inspect.signature()

2、帶引數的裝飾器,也就是根據引數定製乙個裝飾器,可以看成是生產裝飾器的工廠。每次呼叫type_assert,返回乙個特定的裝飾器,然後用它去修飾其他函式

**:

import inspect

# 帶引數的裝飾器,製造工廠的工廠

def type_assert(*ty_args,**ty_kwargs):

def decorator(func):

# a...

func_sig = inspect.signature(func)

bind_type = func_sig.bind_partial(*ty_args,**ty_kwargs).arguments

def wrap(*args,**kwargs):

# b...

for name,obj in func_sig.bind(*args,**kwargs).arguments.items():

type_ = bind_type.get(name)

if type_:

if not isinstance(obj,type_):

raise typeerror('%s must be %s' % (name,type_))

return func(*args,**kwargs)

return wrap

return decorator

@type_assert(c=str)

def f(a,b,c):

pass

>>> def f(a,b,c):

... pass

...

... f_sig = inspect.signature(f)

>>> f_sig.parameters

>>> pa = f_sig.parameters['a']

>>> pa.name

'a'>>> pa.kind

<_parameterkind.positional_or_keyword: 1>

>>> pa.default

>>> ba = f_sig.bind(int,int,str)

>>> ba.arguments

ordereddict([('a', ), ('b', ), ('c', )])

>>> ba.arguments['a']

>>> f_sig.bind(str,list)

traceback (most recent call last):

file "", line 1, in f_sig.bind(str,list)

file "/home/richardo/anaconda3/lib/python3.7/inspect.py", line 3002, in bind

return args[0]._bind(args[1:], kwargs)

file "/home/richardo/anaconda3/lib/python3.7/inspect.py", line 2917, in _bind

raise typeerror(msg) from none

typeerror: missing a required argument: 'c'

>>> f_sig.bind_partial(str,list)

, b=)>

>>>

Python 如何定義帶引數的裝飾器?

案例 實現乙個裝飾器,用它來檢查被裝飾函式的引數型別。需求 裝飾器可以通過函式,指明函式引數型別,進行函式呼叫的時候,傳入引數,檢測到不匹配時,丟擲異常 如何解決這個問題?先要獲取函式的簽名,並且獲得裝飾器中引數,然後把函式簽名和裝飾器中引數對應繫結 把呼叫函式時候傳入的引數和函式簽名進行繫結 把實...

python如何定義帶引數的裝飾器

案例 實現乙個裝飾器,用它來檢查被裝飾函式的引數型別。需求 裝飾器可以通過程式設計客棧函式,指明函式引數型別,進行函式呼叫的時候,傳入引數,檢測到不匹配時,丟擲異常 如何解決這個問題?先要獲取函式的簽名,並且獲得裝飾器中引數,然後把函式簽名和裝飾器中引數對應繫結 把呼叫函式時候傳入的引數和函式簽名進...

裝飾器帶引數

裝飾器帶引數 帶引數的裝飾器是三層的 最外層的函式負責接受裝飾器引數 裡面的內容還是源裝飾器的內容 def outer a 第一層 負責接受引數的 defdecorate func 第二層 負責接受函式的 def wargs,kwargs 第三層 負責接受函式的引數 func wargs print...