Reflection built-in functions and Inspect module in python

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}')
Ce contenu a été publié dans Non classé. Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *