我为记录目的建了一个小装饰器。
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
作为参数传递给包装器,因为在那里如果它不适用于不在类中的方法。
答案 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(如果存在)。