python - how to know if I'm decorating a method -
it seems mymethod not yet method when decorator called.
import inspect class decorator(object): def __call__(self, call): if inspect.ismethod(call): #not working yet obj = "method" args = inspect.getargspec(call)[0][1:] elif inspect.isfunction(call): obj = "function" args = inspect.getargspec(call)[0] elif inspect.isclass(call): obj = "class" args = inspect.getargspec(call.__init__)[0][1:] args="(%s)" % repr(args)[1:-1].replace("'","") print "decorate %s %s%s" % (obj, call.__name__, args) return call @decorator() def myfunction (a,b): pass @decorator() class myclass(): def __init__(self, a, b): pass @decorator() def mymethod(self, a, b): pass if inspect.isfunction(myclass.mymethod): print "mymethod function" if inspect.ismethod(myclass.mymethod): print "mymethod method"
output:
decorate function myfunction(a, b) decorate function mymethod(self, a, b) decorate class myclass(a, b) mymethod method
i know if first argument 'self', there less dirty solution?
edit: why?
i want populate list of callables , arguments, if function or class, , can pass expected arguments, call it, if method, have no "self" argument pass. like:
import inspect class todo(object): calls=[] def do(self, **kwargs): call in self.calls: if 'self' in call.args: print "this fail." args = {} arg in call.args: args[arg]=kwargs.get(arg, none) call.call(**args) todo = todo() class decorator(object): def __call__(self, call): if inspect.isfunction(call): args = inspect.getargspec(call)[0] elif inspect.isclass(call): args = inspect.getargspec(call.__init__)[0][1:] self.call = call self.args = args todo.calls.append(self) return call todo.do(a=1, b=2)
you can't make distinction. here's example:
>>> class a(object): ... pass ... >>> def foo(x): return 3 ... >>> a.foo = foo >>> type(foo) <type 'function'> >>> type(a.foo) <type 'instancemethod'>
as can see, decorator apply foo
, since function. can create class attribute references function create decorated method.
(this example python 2.7; i'm not sure if has changed in python 3 make above behave differently.)
Comments
Post a Comment