How to list all classes and methods/functions in a specific .py file?

Question:

Let’s say we have two python files (say, file_1.py and file_2.py), with the following structure:

-- file_1.py
      # file_1.py imports file_2
      fo(x) # a function
      A  # a class
          fun(y) # some method
          _bo(y) # some "hidden" method
-- file2.py
      bar(x) # a function

I would like some function like get_functions_and_methods('file_1.py') with an output like this:

'fo(x)', 'a.fun(y)', 'a._bo(y)'

Given that I’m a novice in Python, I have no idea how to go about constructing such information, and would be happy for help.

The closest I found online was:

How should I go about solving this? Thanks!

Asked By: Tal Galili

||

Answers:

Say you have a python file with following members

file1.py

def fo(x):
    pass

class A:
    def fun(self, y):
        pass 
    
    def _bo(self, y):
        pass
        
    def NS(y, z):
        pass
        
class B:
    def foo(self, z):
        pass 
    
    def _bar(self, t):
        pass

Expected output would be :

fo(x), A.fun(self, y), A._bo(self, y), A.NS(y, z), B.foo(self, z), B._bar(self, t)

We can use ast module of python to read the python file and its members in its respective format.

Give your file path here
import ast
with open(filepath) as file:
    node = ast.parse(file.read())
Get all the function and classes
result = []
functions = [n for n in node.body if isinstance(n, ast.FunctionDef)]
classes = [n for n in node.body if isinstance(n, ast.ClassDef)]
Add the method to the result in the desired format
def show_info(functionNode):
    function_rep = ''
    function_rep = functionNode.name + '('

    for arg in functionNode.args.args:
        function_rep += arg.arg + ','

    function_rep = function_rep.rstrip(function_rep[-1])
    function_rep += ')'
    return function_rep
Add all functions to the result
for function in functions:
    result.append(show_info(function))
Add all the class methods to the result
for class_ in classes:
    methods = [n for n in class_.body if isinstance(n, ast.FunctionDef)]
    for method in methods:
        result.append((class_.name + '.' + show_info(method)))

Output :

print(', '.join(result))

This gives us the expected result

fo(x), A.fun(self,y), A._bo(self,y), A.NS(y,z), B.foo(self,z), B._bar(self,t)

TL;DR

To run everything at once, just change the filepath in the code below

import ast

with open(r'YOURPYTHONFILEPATH') as file:
    node = ast.parse(file.read())

def show_info(functionNode):
    function_rep = ''
    function_rep = functionNode.name + '('

    for arg in functionNode.args.args:
        function_rep += arg.arg + ','

    function_rep = function_rep.rstrip(function_rep[-1])
    function_rep += ')'
    return function_rep

result = []
functions = [n for n in node.body if isinstance(n, ast.FunctionDef)]
classes = [n for n in node.body if isinstance(n, ast.ClassDef)]

for function in functions:
    result.append(show_info(function))

for class_ in classes:
    methods = [n for n in class_.body if isinstance(n, ast.FunctionDef)]
    for method in methods:
        result.append((class_.name + '.' + show_info(method)))

print(', '.join(result))
# This prints expected output
# fo(x), A.fun(self,y), A._bo(self,y), A.NS(y,z), B.foo(self,z), B._bar(self,t)
Answered By: Himanshuman
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.