Python’s inspect module
provides the introspection of live objects and the source code of the same.
It also provides the introspection of the classes and functions used throughout the program.
The inspect module provides the user to make use of functions/methods in it to fetch the source code for the same, extract and parse the needed library documentation.
This module is used to fetch information about the functions, classes and modules in the particular user’s program. This is made available by performing inspection on the module’s properties, classes/methods of the module, etc.
Python inspect module functionalities
Introspection of a module
Introspection of classes in a module
Introspection of methods/functions in a class
Introspection of objects of a class
Retrieval of source of a class
Retrieval of source of a method/function
Fetching the method signature
Documentation of Strings for a class
Introspecting Class Hierarchies
Introspection of Frames and Stacks in the run-time environment
1. Introspection of a module
Initially, we need to create a sample module along with classes/functions for introspection i.e. test.py
test.py
def funct(arg1, arg2 = 'default', *args):
#module-level function
x = arg1 * 1
return x
class P(object):
def __init__(self, city):
self.city = city
def get_city(self):
return self.city
obj_p = P('sample_instance')
class Q(P):
def country(self):
return ("Hello")
def get_country(self):
return 'Q(' + self.city + ')'
Then we will introspect the created module using inspect.getmembers() function.
Note: The python file containing the sample module and the file containing the introspection code should be placed under the same directory.
Code for Introspection of Module:
import inspect
import test
for city, data in inspect.getmembers(test):
if city.startswith('__'):
continue
print('{} : {!r}'.format(city, data))
Output:
P : <class 'test.P'>
Q : <class 'test.Q'>
funct : <function funct at 0x000001ED62A2EAF0>
obj_p : <test.P object at 0x000001ED62A6A640>
2. Introspection of classes in a module
The getmembers()
function along with the isclass
property identifier is used to inspect the classes within a module.
import inspect
import test
for key, data in inspect.getmembers(test, inspect.isclass):
print('{} : {!r}'.format(key, data))
Output:
P : <class 'test.P'>
Q : <class 'test.Q'>
3. Introspection of methods/functions in a class
The getmembers()
function along with the isfunction
property identifier is used to inspect the classes within a module.
import inspect
from pprint import pprint
import test
pprint(inspect.getmembers(test.P, inspect.isfunction))
Output:
[('__init__', <function P.__init__ at 0x000001D519CA7CA0>),
('get_city', <function P.get_city at 0x000001D519CA7D30>)]
4. Introspection of objects of a class
import inspect
from pprint import pprint
import test
result = test.P(city='inspect_getmembers')
pprint(inspect.getmembers(result, inspect.ismethod))
Output:
[('__init__',
<bound method P.__init__ of <test.P object at 0x00000175A62C5250>>),
('get_city',
<bound method P.get_city of <test.P object at 0x00000175A62C5250>>)]
5. Retrieval of source of a class
The getsource()
functions returns the source of a particular module/class.
import inspect
import test
print(inspect.getsource(test.Q))
Output:
class Q(P):
def country(self):
return ("Hello")
def get_country(self):
return 'Q(' + self.city + ')'
6. Retrieval of source of a method/function
import inspect
import test
print(inspect.getsource(test.Q.get_city))
Output:
def get_city(self):
return self.city
7. Fetching the method signature
The inspect.signature()
method returns the signature of the method, thus making it easy for the user to understand the kind of arguments passed to the method.
import inspect
import test
print(inspect.signature(test.funct))
Output:
(arg1, arg2='default', *args)
8. Documentation of Strings for a class
The inspect module’s getdoc()
function extracts a particular class and its functions to represent to the end-user.
import inspect
import test
print('P.__doc__:')
print(test.P.__doc__)
print()
print('Documentation String(P):')
print(inspect.getdoc(test.P))
Output:
P.__doc__:
Implementation of class P
Documentation String(P):
Implementation of class P
9. Introspecting Class Hierarchies
The getclasstree()
method returns the hierarchy of the classes and its dependencies. It creates a tree-structure using tuples and lists from the given classes.
import inspect
import test
class S(test.Q):
pass
class T(S, test.P):
pass
def print_class_tree(tree, indent=-1):
if isinstance(tree, list):
for node in tree:
print_class_tree(node, indent+1)
else:
print( ' ' * indent, tree[0].__name__ )
if __name__ == '__main__':
print( 'P, Q, S, T:')
print_class_tree(inspect.getclasstree([test.P, test.Q, S, T]))
Output:
P, Q, S, T:
object
P
T
Q
S
T
10. Introspection of Frames and Stacks in the run-time environment
The inspect module also inspects the function’s dynamic environment of the program during its execution. The functions mostly work with call stack and call frames.
currentframe()
depicts the frame at the top of the stack for the current executing function. getargvalues()
results as a tuple with the names of the arguments, and a dicttionary of local values from the frames.
import inspect
def recurse(threshold):
x = '.' * threshold
print (threshold, inspect.getargvalues(inspect.currentframe()))
if threshold <= 0:
return
recurse(threshold - 1)
return
if __name__ == '__main__':
recurse(4)
Output:
4 ArgInfo(args=['threshold'], varargs=None, keywords=None, locals={'threshold': 4, 'x': '....'})
3 ArgInfo(args=['threshold'], varargs=None, keywords=None, locals={'threshold': 3, 'x': '...'})
2 ArgInfo(args=['threshold'], varargs=None, keywords=None, locals={'threshold': 2, 'x': '..'})
1 ArgInfo(args=['threshold'], varargs=None, keywords=None, locals={'threshold': 1, 'x': '.'})
0 ArgInfo(args=['threshold'], varargs=None, keywords=None, locals={'threshold': 0, 'x': ''})
Conclusion
Thus, in this article, we have understood the functionalities offered by the inspect module of Python.
References
- Python inspect module
- inspect module documentation