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.
What You'll Learn in This Lesson
1 inspect.signature: Read a Function's Parameters
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:
2 getsource & Type Tests
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:
3 getmembers & getfullargspec
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.
🎯 YOUR TURN: Fill in the Blanks
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 .)
Common Errors
❌ Calling getsource on REPL / built-in objects
❌ Expecting getmembers to skip dunder methods
🎯 Mini Challenge: Auto-Generate Help
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.
📚 Keep Learning
- inspect — Inspect live objects (official docs)
- inspect.signature & the Signature object
- dir() and getattr() — simpler runtime introspection
Frequently Asked Questions
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 _.
Continue this course
- Previous: The warnings Module
- Next: Weak References (weakref)