Python Introspection: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
No edit summary
Line 86: Line 86:
</font>
</font>


=<tt>getattr()</tt>=
 
=TODO=
https://www.geeksforgeeks.org/code-introspection-in-python/
 
==Module Internal Representation and Introspection==
{{Internal|Python Module Internal Representation and Introspection#Overview|Module Internal Representation and Introspection}}
 
==<tt>getattr()</tt>==
<code>[[Python Language Functions#getattr|getattr()]]</code> is a built-in function that returns the value of the specified attribute from the specified object. If an attribute with such name does not exist, an <code>[[Python Language Exceptions#AttributeError |AttributeError]]</code> exception is thrown.
<code>[[Python Language Functions#getattr|getattr()]]</code> is a built-in function that returns the value of the specified attribute from the specified object. If an attribute with such name does not exist, an <code>[[Python Language Exceptions#AttributeError |AttributeError]]</code> exception is thrown.


==Class Introspection with <tt>getattr()</tt>==
===Class Introspection with <tt>getattr()</tt>===
A specific static method can be identified by querying the class attributes with <code>[[#getmembers.28.29|inspect.getmembers()]]</code> and selecting the matching method, or by name with <code>[[#getattr.28.29|getattr()]]</code> builtin.
A specific static method can be identified by querying the class attributes with <code>[[#getmembers.28.29|inspect.getmembers()]]</code> and selecting the matching method, or by name with <code>[[#getattr.28.29|getattr()]]</code> builtin.
<syntaxhighlight lang='py'>
<syntaxhighlight lang='py'>
Line 101: Line 108:
</syntaxhighlight>
</syntaxhighlight>


=The <tt>inspect</tt> Standard Library Module=
==The <tt>inspect</tt> Standard Library Module==
{{External|https://docs.python.org/3/library/inspect.html#module-inspect}}
{{External|https://docs.python.org/3/library/inspect.html#module-inspect}}


<code>[[Python_Language#inspect|inspect]]</code> is a Standard Library module.
<code>[[Python_Language#inspect|inspect]]</code> is a Standard Library module.


==<tt>getmembers()</tt>==
===<tt>getmembers()</tt>===
<code>getmembers()</code> returns all members of an object as (name, value) pairs sorted by name. The object can be a module, class, etc. A predicate can be provided to the function, and the function returns only return members that satisfy a given predicate.
<code>getmembers()</code> returns all members of an object as (name, value) pairs sorted by name. The object can be a module, class, etc. A predicate can be provided to the function, and the function returns only return members that satisfy a given predicate.


===Module Introspection with <tt>getmembers()</tt>===
====Module Introspection with <tt>getmembers()</tt>====
Also see: {{Internal|Python_Language_Modularization#Module_Introspection|Python Language Modularization}}
Also see: {{Internal|Python_Language_Modularization#Module_Introspection|Python Language Modularization}}


Line 123: Line 130:
</syntaxhighlight>
</syntaxhighlight>


=Invoking Functions and Methods Dynamically=
==Invoking Functions and Methods Dynamically==
{{Internal|Python_Language_Functions#Dynamic_Invocation|Dynamic Invocation}}
{{Internal|Python_Language_Functions#Dynamic_Invocation|Dynamic Invocation}}

Revision as of 03:29, 4 January 2023

Internal

Overview

Introspection is Python's equivalent for Java reflection. It is the ability to determine the type of an object at runtime and to dynamically examine Python objects.

Introspect Members of an Object Instance

All members of an object instance can be identified using inspect.getmembers(). It its most generic form, without any argument, the function returns all members of an object instance as (name, value) tuples, sorted by name. The result will include the reference to the object instance's class, as __class__, instance attributes, methods, etc.:

import inspect

class SampleClass:
    def __init__(self):
        self.color = 'blue'

i = SampleClass()

print(f'{"name".ljust(17)} {"value".ljust(83)} value type')

for (name, value) in inspect.getmembers(i):
    print(f'{name.ljust(17)} {str(value).ljust(83)} {str(type(value))}')

produces:

name              value                                                                               value type
__class__         <class '__main__.SampleClass'>                                                      <class 'type'>
__delattr__       <method-wrapper '__delattr__' of SampleClass object at 0x109144190>                 <class 'method-wrapper'>
__dict__          {'color': 'blue'}                                                                   <class 'dict'>
__dir__           <built-in method __dir__ of SampleClass object at 0x109144190>                      <class 'builtin_function_or_method'>
__doc__           None                                                                                <class 'NoneType'>
__eq__            <method-wrapper '__eq__' of SampleClass object at 0x109144190>                      <class 'method-wrapper'>
__format__        <built-in method __format__ of SampleClass object at 0x109144190>                   <class 'builtin_function_or_method'>
__ge__            <method-wrapper '__ge__' of SampleClass object at 0x109144190>                      <class 'method-wrapper'>
__getattribute__  <method-wrapper '__getattribute__' of SampleClass object at 0x109144190>            <class 'method-wrapper'>
__gt__            <method-wrapper '__gt__' of SampleClass object at 0x109144190>                      <class 'method-wrapper'>
__hash__          <method-wrapper '__hash__' of SampleClass object at 0x109144190>                    <class 'method-wrapper'>
__init__          <bound method SampleClass.__init__ of <__main__.SampleClass object at 0x109144190>> <class 'method'>
__init_subclass__ <built-in method __init_subclass__ of type object at 0x7faabab12f60>                <class 'builtin_function_or_method'>
__le__            <method-wrapper '__le__' of SampleClass object at 0x109144190>                      <class 'method-wrapper'>
__lt__            <method-wrapper '__lt__' of SampleClass object at 0x109144190>                      <class 'method-wrapper'>
__module__        __main__                                                                            <class 'str'>
__ne__            <method-wrapper '__ne__' of SampleClass object at 0x109144190>                      <class 'method-wrapper'>
__new__           <built-in method __new__ of type object at 0x10984c950>                             <class 'builtin_function_or_method'>
__reduce__        <built-in method __reduce__ of SampleClass object at 0x109144190>                   <class 'builtin_function_or_method'>
__reduce_ex__     <built-in method __reduce_ex__ of SampleClass object at 0x109144190>                <class 'builtin_function_or_method'>
__repr__          <method-wrapper '__repr__' of SampleClass object at 0x109144190>                    <class 'method-wrapper'>
__setattr__       <method-wrapper '__setattr__' of SampleClass object at 0x109144190>                 <class 'method-wrapper'>
__sizeof__        <built-in method __sizeof__ of SampleClass object at 0x109144190>                   <class 'builtin_function_or_method'>
__str__           <method-wrapper '__str__' of SampleClass object at 0x109144190>                     <class 'method-wrapper'>
__subclasshook__  <built-in method __subclasshook__ of type object at 0x7faabab12f60>                 <class 'builtin_function_or_method'>
__weakref__       None                                                                                <class 'NoneType'>
color             blue                                                                                <class 'str'>

Introspect Members of an Object Instance Filtering with Predicates

inspect.getmembers() accepts a predicate as the second argument. The predicate is a function applied to the value that must return true or false. The inspect package comes with several predefined predicates:

Predicate Description
inspect.isclass Return true if the value of the member is a class
inspect.ismethod Return true if the value of the member is an instance method
inspect.ismodule Return true if the value of the member is a module
import inspect

class SampleClass:
    def __init__(self):
        self.color = 'blue'

    def some_method(self):
        print('some_method')

i = SampleClass()

for (name, value) in inspect.getmembers(i, inspect.ismethod):
    print(f' method name: {name}')

will display:

method name: __init__
method name: some_method


TODO

https://www.geeksforgeeks.org/code-introspection-in-python/

Module Internal Representation and Introspection

Module Internal Representation and Introspection

getattr()

getattr() is a built-in function that returns the value of the specified attribute from the specified object. If an attribute with such name does not exist, an AttributeError exception is thrown.

Class Introspection with getattr()

A specific static method can be identified by querying the class attributes with inspect.getmembers() and selecting the matching method, or by name with getattr() builtin.

cls = ...
method_name = 'some_static_method'
try:
  method = getattr(cls, method_name)
  print(method)
except AttributeError:
  print(f"{method_name} method not found in class {cls}")

The inspect Standard Library Module

https://docs.python.org/3/library/inspect.html#module-inspect

inspect is a Standard Library module.

getmembers()

getmembers() returns all members of an object as (name, value) pairs sorted by name. The object can be a module, class, etc. A predicate can be provided to the function, and the function returns only return members that satisfy a given predicate.

Module Introspection with getmembers()

Also see:

Python Language Modularization

Find classes in a module:

import inspect

module = sys.modules['some_package.some_subpackage.SomeClass']
class_tuples = inspect.getmembers(module, inspect.isclass)
for ct in class_tuples:
  print('class name: ', ct[0])
  print('class: ', ct[1])

Invoking Functions and Methods Dynamically

Dynamic Invocation