检查方法是否为类方法和调用属性

时间:2015-09-05 08:14:32

标签: python class object decorator python-decorators

我为记录目的建了一个小装饰器。

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

这适用于对象方法和常规方法。我想在多线程中使用它。我有一个包含pid作为对象属性的类。是否可以将装饰器更改为log pid,如果它检测到该方法属于某个类且该类包含属性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

但这根本不起作用。你能帮帮我吗?

摘要

我希望能够从方法(pid)所属的class调用属性func而不将self作为参数传递给包装器,因为在那里如果它不适用于不在类中的方法。

2 个答案:

答案 0 :(得分:3)

方法的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))

答案 1 :(得分:0)

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

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

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

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

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