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 _.