15

I'm playing with Python callable. Basically you can define a python class and implement __call__ method to make the instance of this class callable. e.g.,

class AwesomeFunction(object): def __call__(self, a, b): return a+b 

Module inspect has a function getargspec, which gives you the argument specification of a function. However, it seems I cannot use it on a callable object:

fn = AwesomeFunction() import inspect inspect.getargspec(fn) 

Unfortunately, I got a TypeError:

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.6/inspect.py", line 803, in getargspec raise TypeError('arg is not a Python function') TypeError: arg is not a Python function 

I think it's quite unfortunate that you can't treat any callable object as function, unless I'm doing something wrong here?

1
  • Thank you for reminding me of one of the lesser used and understood magic methods, __call__ Commented Oct 22, 2010 at 18:04

3 Answers 3

10

If you need this functionality, it is absolutely trivial to write a wrapper function that will check to see if fn has an attribute __call__ and if it does, pass its __call__ function to getargspec.

Sign up to request clarification or add additional context in comments.

Comments

6

If you look at the definition of getargspec in the inspect module code on svn.python.org. You will see that it calls isfunction which itself calls:

isinstance(object, types.FunctionType) 

Since, your AwesomeFunction clearly is not an instance of types.FunctionType it fails.

If you want it to work you should try the following:

inspect.getargspec(fn.__call__) 

4 Comments

I know it's expecting a function type. I'm just lamenting the fact that Python didn't design in a way that unifies functions and objects.
It's mainly because Python isn't an outrageously object-oriented language (Java is my best example). In Java, literally everything is an object, to the point where the smallest unit of runnable source is a class. In Python, since such a paradigm was eschewed, yes, a few features are missing, but it's generally clearer.
@EnToutCas: Write a proposal/patch. Might either A) be accepted, or B) shot down with a rationale that demonstrates why it's a bad idea.
@Nick, good idea. Instead of checking for function type, inspect.getargspec just have to check if the arg has the attribute __call__. Although I wouldn't imagine this being accepted as a patch...
0

__call__ defines something that can be called by a class instance. You're not giving getargspec a valid function because you're passing a class instance to it.

The difference between __init and __call__ is this:

fn = AwesomeFunction() # call to __init__ fn(1, 2) # call to __call__ 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.