Reflection built-in functions
Return the type of an object:
def type(object)
The return value is a type object and generally the same object as returned by object.__class__
:
Get the attribute value by its name from an object:
getattr(x, 'y')
is equivalent to x.y
.
If the attribute doesn’t exist an exception is raised but if a default argument is given.
def getattr(__o: object, name: str, __default: _T) -> _T
Return whether the object has an attribute with the given name:
def hasattr(__obj: object, __name: str) -> bool
Return whether an object is an instance of a class or of a subclass of the specified type:
def isinstance(__obj: object, __class_or_tuple: type | tuple[type | tuple[Any, ...], ...]) -> bool
Return whether ‘cls’ is a derived from another class or is the same class:
def issubclass(x: Any, A_tuple: Any) -> bool
Return the __dict__
attribute for a module, class, instance, or any other object with a __dict__
attribute:
def vars(object)
Examples:
from typing import Dict, Sequence from typing import List from typing import Type from foo.bar.FooBar import FooBar def type_examples(): o = FooBar('David', 50) foo_bar_type: Type = type(o) print(f'foo_bar_type={foo_bar_type}') __list = [1, 2] __list_type: Type = type(__list) print(f'__list_type={__list_type}') def getattr_examples(): o = FooBar('David', 50) size: int = getattr(o, 'size') print(f'size={size}') try: getattr(o, 'not_existing_attribute') except Exception as e: print(f'exception={e}') not_existing_value = getattr(o, 'not_existing_attribute', "default value for a not " "existing attribute") print(f'not_existing_value={not_existing_value}') def hasattr_examples(): o = FooBar('David', 50) has_attribute_size: bool = hasattr(o, 'size') print(f'has_attribute_size={has_attribute_size}') has_attribute_unknown: bool = hasattr(o, 'unknown') print(f'has_attribute_unknown={has_attribute_unknown}') def isinstance_examples(): o = FooBar('David', 50) is_foo_bar_object_instance_of_list: bool = isinstance(o, List) print(f'is_foo_bar_object_instance_of_list={is_foo_bar_object_instance_of_list}') l = ['1', '2'] is_list_object_instance_of_list: bool = isinstance(l, List) print(f'is_list_object_instance_of_list={is_list_object_instance_of_list}') is_list_object_instance_of_list_or_dic: bool = isinstance(l, (List, Dict)) print(f'is_list_object_instance_of_list_or_dic={is_list_object_instance_of_list_or_dic}') def issubclass_examples(): is_foo_bar_class_subclass_of_list: bool = issubclass(FooBar, List) print(f'is_foo_bar_class_subclass_of_list={is_foo_bar_class_subclass_of_list}') is_list_class_subclass_of_sequence: bool = issubclass(List, Sequence) print(f'is_list_class_subclass_of_sequence={is_list_class_subclass_of_sequence}') def vars_examples(): o = FooBar('David', 50) vars_of_foo_bar_o = vars(o) print(f'vars_of_foo_bar_o={vars_of_foo_bar_o}') d = { 'a': 1, 'b': 2 } try: vars_of_dic_object = vars(d) except Exception as e: print(f'exception={e}') l = ['1', '2'] try: vars_of_list_object = vars(l) except Exception as e: print(f'exception={e}') print(f'type_examples()') type_examples() print(f'----------') print(f'getattr_examples()') getattr_examples() print(f'----------') print(f'hasattr_examples()') hasattr_examples() print(f'----------') print(f'isinstance_examples()') isinstance_examples() print(f'----------') print(f'issubclass_examples()') issubclass_examples() print(f'----------') print(f'vars_examples()') vars_examples() print(f'----------') |
Output:
type_examples() foo_bar_type=<class 'foo.bar.FooBar.FooBar'> __list_type=<class 'list'> ---------- getattr_examples() size=50 exception='FooBar' object has no attribute 'not_existing_attribute' not_existing_value=default value for a not existing attribute ---------- hasattr_examples() has_attribute_size=True has_attribute_unknown=False ---------- isinstance_examples() is_foo_bar_object_instance_of_list=False is_list_object_instance_of_list=True is_list_object_instance_of_list_or_dic=True ---------- issubclass_examples() is_foo_bar_class_subclass_of_list=False is_list_class_subclass_of_sequence=True ---------- vars_examples() vars_of_foo_bar_o={'name': 'David', 'size': 50} exception=vars() argument must have __dict__ attribute exception=vars() argument must have __dict__ attribute |
Inspect Module overview
It provides functions to get information about live objects such as modules, classes, methods, functions, tracebacks, frame objects, and code objects.
There are four main kinds of services provided by this module:
– types and members checking
– getting source code
– inspecting classes and functions
– examining the interpreter stack
Types and members
The getmembers() function to retrieve the members of an object (instance, class, module…)
The function returns all members of an object as (name, value) pairs sorted by name.
We have two ways to use this function:
– without filter, so all members will be retrieved.
– with a predicate to filter members.
Example:
import inspect from typing import Any import foo.bar.FooBar # How to check if an object start with a specific package: from foo.bar.FooBar import FooBar def retrieve_all_members_of_an_object(): members_of_foo_bar: list[tuple[str, Any]] = inspect.getmembers(FooBar('David', 50)) for m in members_of_foo_bar: print(f'member={m}') def retrieve_all_methods_of_an_object(): members_of_foo_bar: list[tuple[str, Any]] = inspect.getmembers(FooBar('David', 50), predicate=inspect.ismethod) for m in members_of_foo_bar: print(f'member={m}') def retrieve_all_fields_of_an_object(): members_of_foo_bar: dict[str, Any] = FooBar('David', 50).__dict__ for m in members_of_foo_bar: print(f'member={m}') def retrieve_all_functions_of_a_class(): members_of_foo_bar: list[tuple[str, Any]] = inspect.getmembers(FooBar, predicate=inspect.isfunction) for m in members_of_foo_bar: print(f'member={m}') def retrieve_all_functions_of_a_module(): members_of_foo_bar: list[tuple[str, Any]] = inspect.getmembers(foo.bar.FooBar, predicate=inspect.isfunction) for m in members_of_foo_bar: print(f'member={m}') print(f'retrieve_all_members_of_an_object()') retrieve_all_members_of_an_object() print(f'----------') print(f'retrieve_all_methods_of_an_object()') retrieve_all_methods_of_an_object() print(f'----------') print(f'retrieve_all_fields_of_an_object()') retrieve_all_fields_of_an_object() print(f'----------') print(f'retrieve_all_functions_of_a_class()') retrieve_all_functions_of_a_class() print(f'----------') print(f'retrieve_all_functions_of_a_module()') retrieve_all_functions_of_a_module() |
Output:
retrieve_all_members_of_an_object() member=('__class__', <class 'foo.bar.FooBar.FooBar'>) member=('__delattr__', <method-wrapper '__delattr__' of FooBar object at 0x000001DEB8947D90>) member=('__dict__', {'name': 'David', 'size': 50}) member=('__dir__', <built-in method __dir__ of FooBar object at 0x000001DEB8947D90>) member=('__doc__', None) member=('__eq__', <method-wrapper '__eq__' of FooBar object at 0x000001DEB8947D90>) member=('__format__', <built-in method __format__ of FooBar object at 0x000001DEB8947D90>) member=('__ge__', <method-wrapper '__ge__' of FooBar object at 0x000001DEB8947D90>) member=('__getattribute__', <method-wrapper '__getattribute__' of FooBar object at 0x000001DEB8947D90>) member=('__gt__', <method-wrapper '__gt__' of FooBar object at 0x000001DEB8947D90>) member=('__hash__', <method-wrapper '__hash__' of FooBar object at 0x000001DEB8947D90>) member=('__init__', <bound method FooBar.__init__ of FooBar: name=David, size=50>) member=('__init_subclass__', <built-in method __init_subclass__ of type object at 0x000001DEB87DD6C0>) member=('__le__', <method-wrapper '__le__' of FooBar object at 0x000001DEB8947D90>) member=('__lt__', <method-wrapper '__lt__' of FooBar object at 0x000001DEB8947D90>) member=('__module__', 'foo.bar.FooBar') member=('__ne__', <method-wrapper '__ne__' of FooBar object at 0x000001DEB8947D90>) member=('__new__', <built-in method __new__ of type object at 0x00007FFD6BFA5E00>) member=('__reduce__', <built-in method __reduce__ of FooBar object at 0x000001DEB8947D90>) member=('__reduce_ex__', <built-in method __reduce_ex__ of FooBar object at 0x000001DEB8947D90>) member=('__repr__', <bound method FooBar.__repr__ of FooBar: name=David, size=50>) member=('__setattr__', <method-wrapper '__setattr__' of FooBar object at 0x000001DEB8947D90>) member=('__sizeof__', <built-in method __sizeof__ of FooBar object at 0x000001DEB8947D90>) member=('__str__', <method-wrapper '__str__' of FooBar object at 0x000001DEB8947D90>) member=('__subclasshook__', <built-in method __subclasshook__ of type object at 0x000001DEB87DD6C0>) member=('__weakref__', None) member=('name', 'David') member=('size', 50) ---------- retrieve_all_methods_of_an_object() member=('__init__', <bound method FooBar.__init__ of FooBar: name=David, size=50>) member=('__repr__', <bound method FooBar.__repr__ of FooBar: name=David, size=50>) ---------- retrieve_all_fields_of_an_object() member=name member=size ---------- retrieve_all_functions_of_a_class() member=('__init__', <function FooBar.__init__ at 0x000001DEB89DD040>) member=('__repr__', <function FooBar.__repr__ at 0x000001DEB89DD0D0>) ---------- retrieve_all_functions_of_a_module() member=('foo_function', <function foo_function at 0x000001DEB89DADC0>) |
Getting source code
Overview
The module has multiple methods to retrieve source code information.
Here are some helpful and often used.
Return the module an object was defined in:
def getmodule(object: object, _filename: str | None = ...) -> ModuleType
Get the documentation string for an object:
def getdoc(object: object) -> str
Return the name of the Python source file in which an object was defined :
def getsourcefile(object: ModuleType | type | MethodType | FunctionType | TracebackType | FrameType | CodeType | (...) -> Any) -> str
Return the text of the source code for an object:
def getsource(object: ModuleType | type | MethodType | FunctionType | TracebackType | FrameType | CodeType | (...) -> Any) -> str
Examples
import inspect from types import ModuleType from typing import Optional import foo.bar.FooBar from foo.bar.FooBar import FooBar def getmodule_to_check_if_an_object_start_with_a_specific_package(): o = FooBar('David', 50) module: ModuleType = inspect.getmodule(o) print(f'module={module}') print(f'module.__name__={module.__name__}') print(f'module.__package__={module.__package__}') print(f'module.__spec__.origin={module.__spec__.origin}') is_start_with_foo_module: bool = False if module and module.__package__: if module.__package__.startswith("foo"): is_start_with_foo_module = True print(f'is_start_with_foo_module={is_start_with_foo_module}') is_start_with_foo_bar_module: bool = False if module and module.__package__: if module.__package__.startswith("foo.bar"): is_start_with_foo_bar_module = True print(f'is_start_with_foo_bar_module={is_start_with_foo_bar_module}') def getdoc_of_class_and_functions(): o = FooBar('David', 50) doc_for_class: Optional[str] = inspect.getdoc(o) print(f'doc_for_class={doc_for_class}') doc_for_init_method: Optional[str] = inspect.getdoc(o.__init__) print(f'--') print(f'doc_for_init_method={doc_for_init_method}') doc_for_repr_method: Optional[str] = inspect.getdoc(o.__repr__) print(f'--') print(f'doc_for_repr_method={doc_for_repr_method}') a_function_without_documentation: Optional[str] = inspect.getdoc(o.a_function_without_documentation) print(f'--') print(f'a_function_without_documentation={a_function_without_documentation}') def getsourcefile_of_class_module_and_functions(): o = FooBar('David', 50) sourcefile_for_class_FooBar: str = inspect.getsourcefile(FooBar) print(f'sourcefile_for_class_FooBar={sourcefile_for_class_FooBar}') sourcefile_for_module_FooBar: str = inspect.getsourcefile(foo.bar.FooBar) print(f'sourcefile_for_module_FooBar={sourcefile_for_module_FooBar}') sourcefile_for_current_function: str = inspect.getsourcefile( getsourcefile_of_class_module_and_functions) print(f'sourcefile_for_current_function={sourcefile_for_current_function}') def getsource_of_class_module_and_functions(): o = FooBar('David', 50) code_for_class_FooBar: str = inspect.getsource(FooBar) print(f'code_for_class_FooBar={code_for_class_FooBar}') code_for_module_FooBar: str = inspect.getsource(foo.bar.FooBar) print(f'code_for_module_FooBar={code_for_module_FooBar}') code_for_current_function: str = inspect.getsource( getsource_of_class_module_and_functions) print(f'code_for_current_function={code_for_current_function}') print(f'getmodule_to_check_if_an_object_start_with_a_specific_package()') getmodule_to_check_if_an_object_start_with_a_specific_package() print(f'----------') print(f'getdoc_of_class_and_functions()') getdoc_of_class_and_functions() print(f'----------') print(f'getsourcefile_of_class_module_and_functions()') getsourcefile_of_class_module_and_functions() print(f'----------') print(f'getsource_of_class_module_and_functions()') getsource_of_class_module_and_functions() |
Output:
getmodule_to_check_if_an_object_start_with_a_specific_package() module=<module 'foo.bar.FooBar' from 'C:\\programmation\\workspace-python\\python_blog_examples\\inspect\\foo\\bar\\FooBar.py'> module.__name__=foo.bar.FooBar module.__package__=foo.bar module.__spec__.origin=C:\programmation\workspace-python\python_blog_examples\inspect\foo\bar\FooBar.py is_start_with_foo_module=True is_start_with_foo_bar_module=True ---------- getdoc_of_class_and_functions() doc_for_class=It is a dummy class documentation for FooBar. -- doc_for_init_method=constructor for the class. :param name: :param size: -- doc_for_repr_method=Return repr(self). -- a_function_without_documentation=None ---------- getsourcefile_of_class_module_and_functions() sourcefile_for_class_FooBar=C:\programmation\workspace-python\python_blog_examples\inspect\foo\bar\FooBar.py sourcefile_for_module_FooBar=C:\programmation\workspace-python\python_blog_examples\inspect\foo\bar\FooBar.py sourcefile_for_current_function=C:\programmation\workspace-python\python_blog_examples\inspect\getting_source_code_examples.py ---------- getsource_of_class_module_and_functions() code_for_class_FooBar=class FooBar: """ It is a dummy class documentation for FooBar. """ def __init__(self, name: str, size: int) -> None: """ constructor for the class. :param name: :param size: """ self.name = name self.size = size def __repr__(self) -> str: return f'FooBar: name={self.name}, size={self.size}' def a_function_without_documentation(self) -> int: return 0 code_for_module_FooBar=def foo_function(): pass class FooBar: """ It is a dummy class documentation for FooBar. """ def __init__(self, name: str, size: int) -> None: """ constructor for the class. :param name: :param size: """ self.name = name self.size = size def __repr__(self) -> str: return f'FooBar: name={self.name}, size={self.size}' def a_function_without_documentation(self) -> int: return 0 code_for_current_function=def getsource_of_class_module_and_functions(): o = FooBar('David', 50) code_for_class_FooBar: str = inspect.getsource(FooBar) print(f'code_for_class_FooBar={code_for_class_FooBar}') code_for_module_FooBar: str = inspect.getsource(foo.bar.FooBar) print(f'code_for_module_FooBar={code_for_module_FooBar}') code_for_current_function: str = inspect.getsource( getsource_of_class_module_and_functions) print(f'code_for_current_function={code_for_current_function}') |