hofer a écrit :
Hi
Thanks for all of your answers:
Here an example with three of the suggested solutions:
(I didn't succeed in implementing Jason's solution with my
example)
########################################################
import threading
# some objects
a = threading.Event()
b = threading.Event()
c = threading.Event()
d = threading.Event()
def run_dly(o): # a test function
print o,"start",
o.wait(1)
print "stop"
# unmodified test
run_dly(a)
run_dly(b)
run_dly(c)
run_dly(d)
# The new Method
def verbose_wait(self,dly):
print "VERBOSE",
threading._Event.wait(self,dly)
Note that given your use case, you could have used a decorator here
instead...
def verbose(method):
def _verbose(*args, **kw):
print "%s called on %s" % (method.__name__, method.im_self)
print "args : ", args, " - kwargs : ", kw
return method(*args, **kw)
_verbose.__name__ = "verbose wrapper for %s" % method.__name__
return _verbose
b.wait = verbose(b.wait)
Or if you want a more extensible - and "reversible" - solution:
class VerboseMethod(object):
def __init__(self, method, before=None, after=None):
# we only want bound methods here
obj = getattr(method, "im_self", None)
if obj is None:
err = "%s expected a bound method, got %s" % (
type(self), method
)
raise ValueError(err)
self._method = method
self._before = before
self._after = after
def _verbose_before(self, *args, **kw):
"""
You subclass VerboseMethod and taylor this to your own needs,
or alternatively pass a 'before' callback to VerboseMethod
that will get called with method, *args, **kw
"""
if callable(self._before):
self._before(self._method, *args, **kw)
return
# default
m = self._method
print "%s about to be called on %s" % (m.__name__, m.im_self)
print "args : ", args, " - kwargs : ", kw
def _verbose_after(self, result, *args, **kw):
"""
You subclass VerboseMethod and taylor this to your own needs,
or alternatively pass an 'after' callback to VerboseMethod
that will get called with method, result, *args, **kw
"""
if callable(self._after):
self._after(self._method, result, *args, **kw)
return
# default
m = self._method
print "%s called on %s" % (m.__name__, m.im_self)
print "args : ", args, " - kwargs : ", kw
print "result : ", result
def __call__(self, *args, **kw):
self._verbose_before(*args, **kw)
result = self._method(*args, **kw)
self._verbose_after(result, *args, **kw)
return result
def drop(self):
"""restore the original method..."""
obj = self._method.im_self
delattr(obj, self._method.__name__)
class B(object):
def __init__(self, name):
self.name = name
def wait(self, dly=42):
return "%s.wait(%s)" % (self.name, dly)
b1 = B('b1')
b2 = B('b2')
print b1.wait()
print b2.wait()
b1.wait = VerboseMethod(b1.wait)
print b1.wait()
print b2.wait()
b1.wait.drop()
print b1.wait()
print b2.wait()
def before(m, *args, **kw):
print "test before"
print m, args, kw
def after(m, r, *args, **kw):
print "test after"
print m, r, args, kw
b1.wait = VerboseMethod(b1.wait, before=before, after=after)
print b1.wait()
print b2.wait()
b1.wait.drop()
print b1.wait()
print b2.wait()
HTH