检查 method 是否为 class 方法并调用属性

Check whether method is a class method and call attribute

我为日志目的构建了一个小装饰器。

def func_detail(func):
    def func_wrapper(*args,**kwargs):
        log(func.__name__+' ARGS: {}'.format(str(args)))
        return func(*args,**kwargs)
    return func_wrapper

这对对象方法和普通方法都有效。我想在多线程中使用它。我有一个 class,其中包含 pid 作为对象属性。是否可以将装饰器更改为 log pid 如果它检测到该方法属于某些 class 并且此 class 包含属性 pid?

我试过:

def func_detail(func):
    def func_wrapper(*args,**kwargs):
        log('PID: '+self.pid if self.pid is not None else ' '+func.__name__+' ARGS: {}'.format(str(args)))
        return func(*args,**kwargs)
    return func_wrapper

但这根本行不通。你能帮帮我吗?

摘要

我希望能够从方法 (func) 所属的 class 调用属性 pid 而无需将 self 作为参数传递给包装器,因为在那种情况下,它不适用于不在 classes.

内的方法

方法的 self 参数并没有神奇地提供给装饰器中的 func_wrapper 函数。相反,它将是您使用 *args 捕获的第一个位置参数。如果您想使用它,您需要检查 args[0] 并查看它是否具有 pid 属性。

试试这个,它首先检查第一个参数是否存在,然后检查它是否具有 pid 属性:

log('{}FUNC: {} ARGS: {}'.format('PID: {} '.format(args[0].pid)
                                 if args and hasattr(args[0], "pid") else '',
                                 func.__name__, args))

如果调用方法,对象本身将是第一个参数,即方法实现中的self

如果您的装饰器仅应用于方法(定义为 def methodName(self, ...):),您可以捕获 self 中的第一个参数。

然后你可以尝试打印 self.pid 并在没有任何此类属性时捕获异常。

由于自由函数和方法之间几乎没有区别,我认为你应该定义两个装饰器,一个用于自由函数,另一个用于方法,或者定义一个带有参数的装饰器,说明它是否是方法。

另一个解决方案是检查 args 是否不为空,如果存在则打印 args[0].pid。