Reputation: 18745
I built a little decorator for logging purposes.
def func_detail(func):
def func_wrapper(*args,**kwargs):
log(func.__name__+' ARGS: {}'.format(str(args)))
return func(*args,**kwargs)
return func_wrapper
This works for both object methods and normal methods. I want to use it in multithreading. I have a class which contains pid
as an object attribute. Is it possible to change the decorator to log
pid
if it detects that the method belongs to some class and this class contains attribute pid
?
I've tried:
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
But this not works at all. Could you help me?
ABSTRACT:
I want to be able to call attribute pid
from the class
where the method (func
) belongs without passing self
as an argument to the wrapper because in that case it would not works for methods which aren't inside a classes.
Upvotes: 0
Views: 95
Reputation: 86
If you are calling a method, the object itself will be the first parameter, the self
in the method implementation.
If your decorator was only applied to methods (defined as def methodName(self, ...):
) you could capture the first parameter in self.
Then you could try to print self.pid and catch the exception if there isn't any such attribute.
Since there is little distinction between free functions and method, I think that you should define two decorators one for free function, and another for method, or define a decorator taking a parameter saying wether it is a method or not.
Another solution is to check if the args isn't empty and print args[0].pid if it exists.
Upvotes: 0
Reputation: 104762
The self
argument to methods is not magically made available to your func_wrapper
function in your decorator. Rather, it will be the first of the position arguments you're capturing with *args
. If you want to make use of it, you'll need to examine args[0]
and see if it has a pid
attribute.
Try this, which checks first that a first argument exists, then that if it has a pid
attribute:
log('{}FUNC: {} ARGS: {}'.format('PID: {} '.format(args[0].pid)
if args and hasattr(args[0], "pid") else '',
func.__name__, args))
Upvotes: 3