我想编写一个装饰器,该装饰器可应用于单个函数以及嵌套在对象内的函数。困难在于我希望装饰器访问对象变量(通过self.var
)或函数变量(通过kwargs
)。
我的装饰单个函数的示例代码如下:
def outer_decorator(var_to_print):
def inner_decorator(function):
def wrapper(*args, **kwargs):
if var_to_print in kwargs.keys():
string_to_print = kwargs.get(var_to_print, "")
print(string_to_print)
return function(*args, **kwargs)
return wrapper
return inner_decorator
@outer_decorator(var_to_print='var')
def print_something(var=''):
print('print_second')
print_something(var = 'print_first')
#print_first
#print_second
对于对象,我想做类似的事情,但我不想访问kwargs
,而是要访问self.var
:
def wrapper(self, *args, **kwargs):
string_to_print = getattr(self, var_to_print)
print(string_to_print)
return function(self, *args, **kwargs)
关于如何动态检查应使用哪种包装的任何想法?我想检查它是否可调用,但这似乎适用于两者。
您可以isfunction
从检查模块使用。
如果对象是Python函数(包括由lambda表达式创建的函数),则返回True。
>>> from inspect import isfunction
>>> class A():
... pass
...
>>> def f():
... pass
...
>>> a = A()
>>> isfunction(a)
False
>>> isfunction(f)
True
实际上,您想要做的是通过对两者使用相同的装饰器来区分函数和方法。方法仍然是一种功能。从类或类的实例访问它时,它被视为一种方法。
我可以想到两种选择。
@outer_decorator(var_to_print='var', f_type='method')
使用inspect.getfullargspec
的假设下,在你的类,你会用自己的参数名称和您的功能不会。例:
if 'self' in inspect.getfullargspec(f)[0]: