till Kadabra
till Kadabra

Reputation: 488

How do I get a function's full name and arguments as string from a list of function objects in Python?

As the title says, I am interested in a list of all functions inside my python module as string. So far I have a list of function objects with their possible arguments.

For example, with NumPy

from inspect import getmembers, isfunction
import numpy

functions_list = getmembers(numpy, isfunction)
functions_list = [x[1] for x in functions_list] #functions_list = [str(x[1]).split(' ')[1] for x in functions_list]

functions_list[:4]

Output:

[<function numpy.__dir__()>,
 <function numpy.__getattr__(attr)>,
 <function numpy.core.function_base.add_newdoc(place, obj, doc, warn_on_python=True)>,
 <function numpy.alen(a)>]

If I try list comprehension and parse the function object to a string with str(x) as follows:

functions_list = [str(x[1]) for x in functions_list]

Output:

['<function __dir__ at 0x000001C9D44AF310>',
 '<function __getattr__ at 0x000001C9D40BFD30>',
 '<function add_newdoc at 0x000001C9D42C0C10>',
 '<function alen at 0x000001C9D42610D0>']

Same for:

str(functions_list)
repr(functions_list)

I want something like:

['numpy.__dir__()',
 'numpy.__getattr__(attr)',
 'numpy.core.function_base.add_newdoc(place, obj, doc, warn_on_python=True)',
 'numpy.alen(a)']

How can I archive this? I know there are a lot of similar questions here, and I look up a few of them, but I couldn't find something that helps me out.

Upvotes: 0

Views: 800

Answers (2)

wjandrea
wjandrea

Reputation: 33107

There's probably a better way to do this, but you could cobble it together yourself from f.__module__, f.__name__, and the function signature.

import numpy as np
from inspect import signature
f = np.core.function_base.add_newdoc
print(f'{f.__module__}.{f.__name__}{signature(f)}')

Output:

numpy.core.function_base.add_newdoc(place, obj, doc, warn_on_python=True)

But this doesn't work for functions that don't provide a signature, like np.where(). See j1-lee's answer about that.

Upvotes: 1

j1-lee
j1-lee

Reputation: 13939

Although it is not perfect, how about using inspect.signature?

from inspect import getmembers, isfunction, signature
import numpy

def explain(m):
    try:
        return f"{m[0]}{signature(m[1])}"
    except ValueError:
        return f"{m[0]}(???)" # some functions don't provide a signature

print(*(explain(m) for m in getmembers(numpy, isfunction)), sep='\n')

# __dir__()
# __getattr__(attr)
# add_newdoc(place, obj, doc, warn_on_python=True)
# alen(a)
# all(a, axis=None, out=None, keepdims=<no value>, *, where=<no value>)

Upvotes: 4

Related Questions