Search code examples
pythondecoratorintrospection

How do I get the arguments for any python method?


Normally I would use inspect.getargspec, however how do I get the arguments of a method that has been bound?

Eg, how do I get the argument names for the method 'foo' as follows:

class Foo(object):

    @memoized
    def foo(self, arg1, arg2):
        pass

Note that Foo().foo is a memoized object, http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize

This means that it is really a functools.partial instance.

How do I get the original function or alternatively, obtain the arguments somehow?

If I can't, does this indicate a design flaw of the PythonDecoratorLibrary?


Solution

  • You could add a _wrapped attribute to the partial, which may be what you did already:

    def __get__(self, obj, objtype):
        """Support instance methods."""
        f = functools.partial(self.__call__, obj)
        f._wrapped = self.func
        return f
    

    Or you could return self.func instead of the partial if obj is None (i.e. if it's accessed from the class instead of an instance):

    def __get__(self, obj, objtype):
        """Support instance methods."""
        if obj is None:
            return self.func
        else:
            return functools.partial(self.__call__, obj) 
    

    The partial's func attribute is the memoized object's __call__ method. If you call it from a Foo instance, then the first argument is set to the instance obj by the partial (see this in Foo().foo.args). Then in memoized.__call__, self.func(*args) works like a poor man's bound method.

    For the lru_cache, Raymond Hettinger has Python 2 compatible implementations available as ActiveState Code Recipes. There's also a version for least frequently used, in addition to least recently used.