Introspection with inspect

The inspect module lets your program examine its own functions, classes, and modules at runtime — reading signatures, source code, and members on the fly.

Learn Introspection with inspect in our free Python course — an interactive lesson with runnable examples, a practice exercise and a quick reference.

Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

It's the engine behind documentation generators, test frameworks, and CLI builders. Learn it and you can write tools that adapt to any code handed to them.

inspect.signature(func) returns a Signature object whose .parameters maps each parameter name to details — its kind (positional, keyword-only, etc.) and its default value. This is how a CLI tool figures out what arguments a command takes:

inspect.getsource(obj) returns the exact source text of a function or class — as long as it was defined in a real file. The is* predicates ( isfunction , isclass , ismethod , ismodule ) tell you what kind of object you're holding:

getmembers(obj, predicate) returns every member that passes a test — pass inspect.isfunction to list a class's methods. getfullargspec(func) breaks a signature into plain lists, handy when you want simple names for positional, keyword-only, and variadic args:

Together these let you walk an unknown object and discover its shape — which methods it offers and how to call them — the heart of "auto-wiring" frameworks.

Fill in each ___ so the code reports the function's parameter names. (Hint: the modern API is inspect.signature , and its parameters live in .parameters .)

❌ Calling getsource on REPL / built-in objects

❌ Expecting getmembers to skip dunder methods

Build a tiny help generator: for every function in a small registry, print its name and signature using inspect.signature — exactly how CLI frameworks build their --help output.

Lesson complete — your code can read itself!

You can read parameters with inspect.signature , fetch source with getsource , classify objects with isfunction and isclass , list members with getmembers , and dissect arguments with getfullargspec — the toolkit behind real framework magic.

🚀 Up next: weak references — hold onto objects without preventing them from being cleaned up.

Practice quiz

What does the inspect module let your program do?

  • Speed up function calls
  • Compile Python to C
  • Examine its own functions, classes, and modules at runtime
  • Encrypt source code

Answer: Examine its own functions, classes, and modules at runtime. inspect lets code introspect itself — reading signatures, source, and members at runtime.

What does inspect.signature(func) return?

  • A Signature object with a .parameters mapping
  • The function's return value
  • The function's source code
  • A list of argument names only

Answer: A Signature object with a .parameters mapping. signature returns a Signature object whose .parameters maps each name to a Parameter with kind and default.

How do you tell a required parameter from an optional one?

  • Check if its name starts with an underscore
  • It appears first in the list
  • Its kind is VAR_KEYWORD
  • Its default is inspect.Parameter.empty

Answer: Its default is inspect.Parameter.empty. A required parameter has no default, represented by the sentinel inspect.Parameter.empty.

Why compare param.default against inspect.Parameter.empty with 'is' rather than '=='?

  • '==' is slower
  • It is a sentinel object, so identity comparison with 'is' is correct
  • 'is' works on strings only
  • There is no difference

Answer: It is a sentinel object, so identity comparison with 'is' is correct. Parameter.empty is a sentinel; compare against it with 'is' (identity), not '=='.

What does inspect.getsource(obj) return?

  • The exact source text of the object, if defined in a real file
  • The bytecode
  • The docstring only
  • The function's signature

Answer: The exact source text of the object, if defined in a real file. getsource returns the source text, as long as the object was defined in a real .py file.

Why does inspect.getsource sometimes raise OSError?

  • The function is too large
  • The function has no arguments
  • There is no source file (e.g. typed at the REPL or built with exec)
  • The object is a string

Answer: There is no source file (e.g. typed at the REPL or built with exec). getsource needs a real source file; objects from the REPL or exec have none, raising OSError/TypeError.

For a normal def add(a, b), what does inspect.isfunction(add) return?

  • False
  • True
  • None
  • An error

Answer: True. isfunction is True for a Python function defined with def; isclass(add) would be False.

What does inspect.getmembers(Robot, inspect.isfunction) give you?

  • Every attribute of Robot
  • Only data attributes
  • The source of Robot
  • Only the members that are functions (its methods)

Answer: Only the members that are functions (its methods). getmembers(obj, predicate) returns members passing the test — isfunction lists the class's methods.

For def configure(host, port=8080, *args, debug=False, **kwargs), what is getfullargspec(...).kwonlyargs?

  • host
  • port

Answer: port. Keyword-only parameters appear after the *args; here only debug is keyword-only.

What does getmembers return that you often need to filter out?

  • Only the methods you defined
  • Nothing extra
  • Inherited and __dunder__ members too
  • Only data attributes

Answer: Inherited and __dunder__ members too. getmembers also returns inherited and dunder members, so you usually filter names starting with _.