温馨提示:本文翻译自stackoverflow.com,查看原文请点击:python - Determine whether function is nested within object
python

python - 确定函数是否嵌套在对象中

发布于 2020-03-28 23:20:01

我想编写一个装饰器,该装饰器可应用于单个函数以及嵌套在对象内的函数。困难在于我希望装饰器访问对象变量(通过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)

关于如何动态检查应使用哪种包装的任何想法?我想检查它是否可调用,但这似乎适用于两者。

查看更多

查看更多

提问者
Carsten
被浏览
17
abc 2020-01-31 21:17

您可以isfunction检查模块使用。

如果对象是Python函数(包括由lambda表达式创建的函数),则返回True。

>>> from inspect import isfunction
>>> class A():
...     pass
... 
>>> def f():
...     pass
... 
>>> a = A()
>>> isfunction(a)
False
>>> isfunction(f)
True

实际上,您想要做的是通过对两者使用相同的装饰器来区分函数和方法。方法仍然是一种功能。从类或类的实例访问它时,它被视为一种方法。
我可以想到两种选择。

  1. 向装饰器添加参数 @outer_decorator(var_to_print='var', f_type='method')
  2. 使用inspect.getfullargspec的假设下,在你的类,你会用自己的参数名称和您的功能不会。例:

    if 'self' in inspect.getfullargspec(f)[0]: