I have the following descriptor, which saves the configuration inside my class after a method which is annotated with @saveconfig
is called:
class saveconfig(object):
def __init__(self, f):
self.f = f
def __get__(self, instance, owner):
def wrapper(*args):
self.f(instance, *args)
instance.cfg.write()
instance.paramcfg.write()
return wrapper
It's used like this:
class pbtools():
@saveconfig
def getip(self, ip):
(...)
It works fine. Now i want to get the decorated method by using getattr. But since the method is wrapped by the descriptor, i only get wrapper
as a result:
pbt = pbtools()
# results in "<function wrapper at 0x23cced8>:"
method = getattr(pbt, "getip")
How can i access the wrapped method getip
with getattr, to be able to call it by it's name? (of course i cannot access the method directly otherwise i would not have to do that).
Additional explanation:
The script is called from commandline. I have to map a command line parameter (string) to a method with the same name to invoke it. Furthermore, i have to map any additional parameters from the comamndline to parameters of the method, like this:
pbtools getip 192.168.178.123 #-> calls getip with parameter 192.168.178.123
Since i cannot get the original method, i don't know how many parameters it has to map them. I have several methods that are decorated like that, because i want to move the cross cutting concern of saving the config out of the methods in the pbtools-class.
I'm still not 100% sure I fully understand your problem. You say that "Since i cannot get the original method, i don't know how many parameters it has to map them", but you don't need access to the original method to call by variable number of arguments (since the decorator has
*args
). You can do something like this:You can also simplify your decorator a bit. It doesn't really need the
__get__
mechanism.The
functools.wraps
is a helper decorator that makes the wrapper mimic the original function (i.e. it copies the function name, docstring and stuff like that). It will make debugging easier, since you will know where exceptions are originating from etc.