Introspection or reflection is the ability of software to identify and report their own internal structures, such as types, variable scope, methods and attributes.
Native interpreter functions for introspection:
| Function | Returns |
|---|---|
type(object) |
The typo (class) of the object |
id(object) |
object identifier |
locals() |
local variables dictionary |
globals() |
global variables dictionary |
vars(object) |
object symbols dictionary |
len(object) |
size of an object |
dir(object) |
A list of object structures |
help(object) |
Object doc strings |
repr(object) |
Object representation |
isinstance(object, class) |
True if object is derived from class |
issubclass(subclass, class) |
True if object inherits the class |
The object identifier is an unique number that is used by the interpreter for identifying the objects internally.
Example:
In [1]:
# Getting some information
# about global objects in the program
from types import ModuleType
def info(n_obj):
# Create a referênce to the object
obj = globals()[n_obj]
# Show object information
print 'Name of object:', n_obj
print 'Identifier:', id(obj)
print 'Typo:', type(obj)
print 'Representation:', repr(obj)
# If it is a module
if isinstance(obj, ModuleType):
print 'itens:'
for item in dir(obj):
print item
print
# Showing information
for n_obj in dir()[:10]: # The slice [:10] is used just to limit objects
info(n_obj)
Python also has a module called types, which has the definitions of the basic types of the interpreter.
example:
In [2]:
import types
s = ''
if isinstance(s, types.StringType):
print 's is a string.'
Through introspection, it is possible to determine the fields of a database table, for example.
The module inspect provides a set of high-level functions that allow for introspection investigate types, collection items, classes, functions, source code and the runtime stack of the interpreter.
example:
In [3]:
import os.path
# inspect: "friendly" introspection module
import inspect
print 'Object:', inspect.getmodule(os.path)
print 'Class?', inspect.isclass(str)
# Lists all functions that exist in "os.path"
print 'Member:',
for name, struct in inspect.getmembers(os.path):
if inspect.isfunction(struct):
print name,
The functions that work with the stack of the interpreter should be used with caution because it is possible to create cyclic references (a variable that points to the stack item that has the variable itself). The existence of references to stack items slows the destruction of the items by the garbage collector of the interpreter.
In [1]:
Out[1]: