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 to list all classes and methods/functions in a package – with a full folder/file path? which solves this for a module, but I can’t seem to adjust it to .py files. I tried importing the .py file using
__import__
(from here: Import file using string as name), it didn’t seem to work. The issue is that I don’t just want to capture all of the def, but also connect them to classes if they are embedded within them.
How should I go about solving this? Thanks!
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)
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 to list all classes and methods/functions in a package – with a full folder/file path? which solves this for a module, but I can’t seem to adjust it to .py files. I tried importing the .py file using
__import__
(from here: Import file using string as name), it didn’t seem to work. The issue is that I don’t just want to capture all of the def, but also connect them to classes if they are embedded within them.
How should I go about solving this? Thanks!
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)