Python Introspection
By Flavio Copes
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
Related posts about python: