Python Introspection

By

Learn how introspection works in Python, using help(), type(), dir(), and id() to inspect functions and objects, plus the inspect module for more detail.

~~~

Introspection is the ability of a program to examine its own objects at runtime. Python is very good at this: functions, variables and objects can all tell you what they are, what they contain, and what you can do with them.

This is handy when you’re exploring a library in the REPL, or when you’re debugging and a variable is not what you expected.

Getting the documentation

Using the help() global function we can get the documentation, if provided in form of docstrings:

help(print)

This prints the signature of print() and a description of each parameter, right in the terminal.

Printing objects

You can use print() to get information about a function:

def increment(n):
    return n + 1

print(increment)

# <function increment at 0x7f420e2973a0>

or an object:

class Dog():
    def bark(self):
        print('WOF!')

roger = Dog()

print(roger)

# <__main__.Dog object at 0x7f42099d3340>

Checking the type

The type() function gives us the type of an object:

print(type(increment))
# <class 'function'>

print(type(roger))
# <class '__main__.Dog'>

print(type(1))
# <class 'int'>

print(type('test'))
# <class 'str'>

Listing methods and attributes

The dir() global function lets us find out all the methods and attributes of an object:

print(dir(roger))

# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bark']

Most of those double-underscore entries are inherited from object. The interesting one here is bark, the method we defined.

Once you know a name, hasattr() tells you if the object has it, and getattr() fetches it:

print(hasattr(roger, 'bark'))
# True

getattr(roger, 'bark')()
# WOF!

This is useful when the attribute name is only known at runtime, for example when it comes from configuration.

Where objects live in memory

The id() global function shows us the location in memory of any object:

print(id(roger)) # 140227518093024
print(id(1))     # 140227521172384

It can be useful to check if two variables point to the same object.

Be careful with one thing: two objects that look equal are not necessarily the same object. Two separate Dog() instances with identical data have different ids. Use == to compare values, and is (which compares ids) only when you really mean “the same object”.

The inspect module

The inspect standard library module gives us more tools. For example we can get the signature of a function:

import inspect

print(inspect.signature(increment))
# (n)

You can check out everything it offers here: https://docs.python.org/3/library/inspect.html

Tagged: Python · All topics
~~~

Related posts about python: