## Monday, January 30, 2017

### Finding the arity of a Python function

By Vasudev Ram

While browsing through some Python code, I had the idea of trying to find the arity of a Python function. The arity of a function is the number of arguments it takes.

Digression: I had first come across the concept of arity when reading some books on functional or logic programming, years ago. E.g. Prolog has the concept of arity, IIRC. Just did a quick search for the phrase prolog arity and found a few results confirming this. Here is one, from cse.unsw.edu.au:

But in Prolog, the word arity is related to a functor (link 2), not a function, according to the page at link 2.

Excerpt from link 1:

[ The arity of a functor is the number of arguments it takes. For example, the arity of likes/2, as in likes(jane, pizza), is 2, as it takes two arguments, jane and pizza. ]

In fact the use of likes/2 gives a clue to the fact that the Erlang language was influenced by Prolog (and I've read that the first version of Erlang was written in Prolog), because a function foo with arity 2 in Erlang is written as foo/2, as for the Prolog functor above.

[ Note: I'm not an expert in either Prolog or Erlang; these are just casual observations. Anyone who knows better, feel free to comment / correct. ]

Anyway, end of digression.

Here is the code I came up with to find the arity of a Python function. I've used the isfunction and getargspec functions of the inspect module.
```'''
function_arity.py
Purpose: To find the arity of a Python function.
Author: Vasudev Ram
Copyright 2017 Vasudev Ram
Web site: https://vasudevram.github.io
'''

import inspect

# Define a few functions with increasing arity:

def f0():
pass

def f1(a1):
pass

def f2(a1, a2):
pass

def f3(a1, a2, a3):
pass

def f4(a1, a2, a3, a4):
pass

def main():

# Define a few non-function objects:
int1 = 0
float1 = 0.0
str1 = ''
tup1 = ()
lis1 = []

# Test the function arity-finding code with both the functions
# and the non-function objects:
for o in (f0, f1, f2, f3, f4, int1, float1, str1, tup1, lis1):
if not inspect.isfunction(o):
print repr(o), 'is not a function'
continue
n_args = len(inspect.getargspec(o)[0])
if n_args == 0:
num_suffix = '(no) args'
elif n_args == 1:
num_suffix = 'arg'
else:
num_suffix = 'args'
print o.__name__, 'is a function that takes', \
n_args, num_suffix

if __name__ == '__main__':
main()
```
And here is the output when I run the program:
```\$ python function_arity.py
f0 is a function that takes 0 (no) args
f1 is a function that takes 1 arg
f2 is a function that takes 2 args
f3 is a function that takes 3 args
f4 is a function that takes 4 args
0 is not a function
0.0 is not a function
'' is not a function
() is not a function
[] is not a function
```

I also did a web search:

in which one hit showed another way of doing it (using gettattr). This StackOverflow question:

How to find out the arity of a method in Python

had some answers; the ones by Python guru Alex Martelli (the martellibot) and Anurag Uniyal were interesting.

Enjoy.

- Vasudev Ram - Online Python training and consulting

Get updates (via Gumroad) on my forthcoming apps and content.

Jump to posts: Python * DLang * xtopdf

My ActiveState Code recipes