Development Python

Python inspect module

Overview

Ever wondered how cool would it be to have the power to actually get the source code of some other Python module in your own Program? This will open ideas and doors to so many opportunities like processing the source code of a module, gettings its docstring, producing documentation for a piece of code automatically. Let me tell you, this is 100% possible with Python’s inspect module.

Python inspect module

Python inspect module allows us to inspect objects of a running program, get the source code of a module, get the docstring associated with that module, read the method signature of a function in Python and much more. This way, we can build projects which produce live code documentation for our own projects. This means that we only have to make necessary comments on our Python code and we can leave the rest of the job to Python itself to produce the documentation for us.

Using sample code

To understand how Python’s inspect module works, we will use one of our own sample code definition in Python which just demonstrates inheritance in Python and how objects are made. Let’s look at the sample module we will be using in rest of the tutorial here:

def module_level_function(arg1, arg2 = 'default', *args):
    """I am a module-level function."""
    local_var = arg1 * 2
    return local_var

class Person(object):
    """Definition for Person class."""

    def __init__(self, name):
        self.name = name

    def get_name(self):
        "Returns the name of the instance."
        return self.name

person_obj = Person('sample_instance')

class Student(Person):
    """This is the Student class, child of Person class.
    "
""

    # This method is not part of Person class.
    def do_something_else(self):
        """Anything can be done here."""

    def get_name(self):
        "Overrides version from Person class"
        return 'Student(' + self.name + ')'

We have defined a sample module so that we can start extracting the source code and other components from it in later examples we write. Let’s get started.

Inspecting module

The above Python module is saved in a file called linuxhint.py in the same directory where we will make our new Python scripts. We can inspect a module in Python by first making an import for it. This import statement will be present in all scripts we write in later sections as well. Here is a sample program with which we inspect our module:

import inspect
import linuxhint

for name, data in inspect.getmembers(linuxhint):
    if name.startswith('__'):
        continue
    print('{} : {!r}'.format(name, data))

Here is what we get back with this command:

Python inspect module

Python inspect module


The output provides us the details about how many classes, functions and objects exist in this module when the script is run.

Inspecting classes in a Module

The above example we showed presented all details of a module at once. if we want to get only the information related to the classes in the module, we can get the same as:

import inspect
import linuxhint

for key, data in inspect.getmembers(linuxhint, inspect.isclass):
    print('{} : {!r}'.format(key, data))

Let’s see the output for this command:

Python inspect module class

Python inspect module class


The output is exactly the same, only that this time, only the class definitions were printed to the console.

Inspecting methods in a class

The methods are the one which defines the behaviour of a class in OOPs and provide information about how an Objects behaviour will be modified as the methods are called upon them. It is due to this reason it is important to document all methods which exist in a class or a module. We can get information related to a method like this:

import inspect
from pprint import pprint
import linuxhint

pprint(inspect.getmembers(linuxhint.Person, inspect.isfunction))

Here is what we get back with this command:

Inspecting a method of class

Inspecting a method of class


The output just displays the method definition of each method present.

Inspecting objects of a class

When you introspect about how much space is occupied when we run a Python script, it is important to know how many objects for the class are instantiated for the class in a program. To know this, we can get information about Objects of a class in a module as well:

import inspect
from pprint import pprint
import linuxhint

person = linuxhint.Person(name='inspect_getmembers')
pprint(inspect.getmembers(person, inspect.ismethod))

Let’s see the output for this command:

Inspecting Objects of class

Inspecting Objects of class


This also prints the memory address where this object lives during the course of this program.

Inspecting Docstring of a class

The docstring of a module is the part which actually informs a user or a developer that what this module is about and what features does it provides. With the inspect module, we can get the docstring of a complete module to document it better. Let’s see how we can extract docstring for a class:

import inspect
import linuxhint

print('Person.__doc__:')
print(linuxhint.Person.__doc__)
print()
print('getdoc(Person):')
print(inspect.getdoc(linuxhint.Person))

Here is what we get back with this command:

Getting Docstring for class

Getting Docstring for class

Inspecting Source of a class

Finally, we can see how we can extract complete source code of a class in a Python program as well. This is an important feature as well as this help us to build documentation tools about a Python module. Let’s see an example in action:

import inspect
import linuxhint

print(inspect.getsource(linuxhint.Student))

Here is what we get back with this command:

Getting Source code of class

Getting Source code of class

Inspecting Source of a method

The same way we extracted source code of a class, we will now extract the source code of a method in our Python program:

import inspect
import linuxhint

print(inspect.getsource(linuxhint.Student.get_name))

Here is what we get back with this command:

Getting Source of method in a class

Getting Source of method in a class

Inspecting Method Signature

The signature of a method provide a deep insight about what a method does and what input does it takes. It provides us the power to document a method better because documentation of a method is incomplete without knowing what input does it take. Here is how we can extract the information related to a method signature:

import inspect
import linuxhint

print(inspect.signature(linuxhint.module_level_function))

Here is what we get back with this command:

Getting Signature of a Method

Getting Signature of a Method

Conclusion

In this lesson, we looked at how we can make use of Python inspect module to look at source code and many other internal features of a Python program. Read more Python based posts here.

About the author

Shubham Aggarwal

Shubham Aggarwal

I’m a Java EE Engineer with about 4 years of experience in building quality products. I have excellent problem-solving skills in Spring Boot, Hibernate ORM, AWS, Git, Python and I am an emerging Data Scientist.