要实现这一点,您可以使用inspect 模块。使用getfullargspec 函数,您可以访问函数中定义的所有参数名称。需要注意的是,如果您想参数化传递给装饰函数的默认值,您将需要一个装饰器工厂。这是一个代码示例:
import inspect
def my_decorator(default_value): # define decorator factory
def decorator(fn): # define decorator
def inner(*args, **kwargs):
fn_args = inspect.getfullargspec(fn).args # recover decorated function
# arguments
if "magic_word" in fn_args: # check for argument
return fn(*args, magic_word=default_value, **kwargs)
else:
return fn(*args, **kwargs)
return inner
return decorator
@my_decorator(default_value='Goodbye World')
def function_1():
print('Hello World')
@my_decorator(default_value='Goodbye World')
def function_2(magic_word):
print(magic_word)
使用此装饰器,以下代码的结果将是:
>>> function_1()
'Hello World'
>>> function_2()
'Goodbye World'
请注意,如果您只有关键字参数,则必须稍微修改装饰器:
def my_decorator(default_value): # define decorator factory
def decorator(fn): # define decorator
def inner(*args, **kwargs):
fn_args = inspect.getfullargspec(fn).args # recover decorated function
# arguments
fn_args += (inspect.getfullargspec(fn).kwonlyargs) # add kwonly args
if "magic_word" in fn_args: # check for argument
return fn(*args, magic_word=default_value, **kwargs)
else:
return fn(*args, **kwargs)
return inner
return decorator
@my_decorator(default_value='Goodbye World')
def function_3(a, *, magic_word):
print(a, magic_word)
>>> function_3(1)
1 Goodbye World
请注意,此实现有一个重要限制,即您必须对要查找的参数名称进行硬编码。情况就是这样,因为 python 不能评估参数名称的表达式。例如,如果你尝试这个实现:
def my_decorator(search_word, default_value): # define decorator factory
def decorator(fn): # define decorator
def inner(*args, **kwargs):
fn_args = inspect.getfullargspec(fn).args # recover decorated function
# arguments
fn_args += (inspect.getfullargspec(fn).kwonlyargs) # add kwonly args
if search_word in fn_args: # check for argument
return fn(*args, search_word=default_value, **kwargs)
else:
return fn(*args, **kwargs)
return inner
return decorator
@my_decorator(search_word='magic_word', default_value='Goodbye World')
def function_4(magic_word):
print(magic_word)
运行代码会报错:
>>> function_4()
Traceback (most recent call last):
File "/test.py", in <module>
function_4()
File "/test6.py", in inner
return fn(*args, search_word=default_value, **kwargs)
TypeError: function_4() got an unexpected keyword argument 'search_word'