2

I have a Python module 'something.py' and I'd like to get a list of all of the functions I've written in this file. I've followed this SO post explaining the standard ways of doing this.

The trouble is I have import functions in something.py, so when trying to list my functions I also list the imported functions I don't care about. How can I get a list of the functions that I wrote in something.py?

Visipi
  • 23
  • 1
  • 5
  • Are you sure the answers in your [reference](https://stackoverflow.com/questions/139180/how-to-list-all-functions-in-a-python-module) don't work? For instance in the comments of the answer by adnan we see that `from inspect import getmembers, isfunction; import something; functions_list = getmembers(something, isfunction)` provides a list only of functions in something module (i.e. functions of imports not included). – DarrylG Aug 17 '20 at 09:26
  • Unfortunately not, and I was surprised by this too. It works as expected when I comment my imports out but otherwise it fails. I suspect the problem is that I'm importing everything in my project's package which is probably causing it to behave differently than if I was just trying to import something from the standard library. – Visipi Aug 17 '20 at 09:33
  • @Visipi--that's surprising since it works in my simple test program which 1) imports a module something and 2) something.py module imports something_else plus the math library. – DarrylG Aug 17 '20 at 09:42
  • Ah, thank you for sanity testing. Above and beyond. I'm quite sure now the problem is me. Probably something weird in my __init__ file. I'll consider that answered but I'm not sure how to give you points for a comment. – Visipi Aug 17 '20 at 09:50
  • @Visipi--actually in this case I think stackoverflow (SO) considers it an unsuitable question since the problem can't be reproduced (i.e. thus any answer can't be used by others). In which case, I think SO suggest removing the question, but I could be wrong. – DarrylG Aug 17 '20 at 09:55
  • I'll check. Thanks for your help @DarrylG! – Visipi Aug 17 '20 at 09:59
  • @DarrylG In my test, that solution does not do what the OP wants. My `something` modules has this import: `from textwrap import dedent`. And the return from `getmembers()` includes `dedent`. – FMc Aug 17 '20 at 10:25
  • @FMc--you're right. If something module has: `import something_else` (where something_else) is some other module then it does not show in the list of functions. But, if you use from something_else import foo`, then foo does show in the list of functions. – DarrylG Aug 17 '20 at 10:32
  • @FMc--here's an old version of the question from 11 years ago--[Find functions explicitly defined in a module ](https://stackoverflow.com/questions/1106840/find-functions-explicitly-defined-in-a-module-python) which worked once I updated the code to Python 3 (i.e. changed `itervalues` to `values`) – DarrylG Aug 17 '20 at 10:59

4 Answers4

3

Updating functions from this answer--Find functions explicitly defined in a module from Python 2 to 3 (i.e. replace itervalues() with values():

def is_mod_function(mod, func):
    ' checks that func is a function defined in module mod '
    return inspect.isfunction(func) and inspect.getmodule(func) == mod


def list_functions(mod):
    ' list of functions defined in module mod '
    return [func.__name__ for func in mod.__dict__.values() 
            if is_mod_function(mod, func)]

Usage

print(list_functions(something))  # Output: ['a1', 'b1']

File main.py (Main module)

import inspect
import something  # project module

def is_mod_function(mod, func):
    return inspect.isfunction(func) and inspect.getmodule(func) == mod


def list_functions(mod):
    return [func.__name__ for func in mod.__dict__.values() 
            if is_mod_function(mod, func)]

def list_functions1(mod):
    return [func.__name__ for func in mod.__dict__.itervalues() 
            if is_mod_function(mod, func)]


# Get list of functions defined only in module something
print(list_functions(something))

File something.py (something module)

from textwrap import dedent
from math import sin, cos
import numpy as np

def a1():
  pass

def b1():
  pass

Output

['a1', 'b1']  # shows only the functions defined in something.py
DarrylG
  • 16,732
  • 2
  • 17
  • 23
2
import <modulename>
dir(modulename)

2nd line of code will give the list of functions present in the module

Eg:

import math
dir(math)
['__doc__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
  • Yes, but dir() also lists every imported function in that file For example, suppose I have numpy imported into something.py. When I print dir(something), I'm not interested in seeing things from numpy. – Visipi Aug 17 '20 at 09:22
2

The getmembers() function includes imported functions, so you need more. One idea is to check the name of the module of the function.

from inspect import getmembers, isfunction
import something
import sys

mod = something

funcs = [
    f
    for _, f in getmembers(mod, isfunction)
    if f.__module__ == mod.__name__
]

for f in funcs:
    print(f)

Or you could do the filtering with this conditional instead:

if sys.modules[f.__module__] is mod

Either way, the output is:

<function bar at 0x107fb05f0>
<function foo at 0x107f840e0>

My something module has this:

import sys
from textwrap import dedent

fubb = 1

def foo():
    pass

def bar():
    pass
FMc
  • 41,963
  • 13
  • 79
  • 132
0

You can use dir(yourModule) to return a list of attributes: https://docs.python.org/3/library/functions.html#dir

barbaart
  • 837
  • 6
  • 14
  • But dir(yourModule) also lists the functions I imported in 'yourModule.' I'm only interested in listing the functions I wrote. – Visipi Aug 17 '20 at 09:25
  • yes you're right, sorry about that. I'm not sure if thats possible.. Have you figured it out already ? – barbaart Aug 25 '20 at 12:13