Python Object introspection helps us to determine the type of object at runtime, however, this is one of Python’s strength. In Python everything is an object hence we can examine these objects using introspection.

How to Introspect an Object:

Python provides a few inbuilt functions and modules to accomplish this, let’s examine those.

1. Python dir:

The dir is the most important function for object introspection, it typically returns a list of attributes and functions belonging to that object.

data = {
    "id":"123",
    "name":"chandra"
}
print(dir(data))

Output:

['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
 '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', 
 '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', 
 '__sizeof__', '__str__', '__subclasshook__', 
 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

The above output (introspection) gives us the list of methods of dict object in python, so it helps us to recollect the method names.

2. Python type:

The type function returns the type of an object.

name = ""
print(type(name))
print(type(123))
print(type([]))
print(type({}))
print(type(()))

Output:

<class 'str'>
<class 'int'>
<class 'list'>
<class 'dict'>
<class 'tuple'>

3. Python id:

The id function returns the unique if an object

ids = [123,342,123]
print(id(ids))

Output:

4391431432

4. Python inspect module:

The Python built-in inspect modules also provide several methods to introspect the live object. For example here is the example to get the member of a dict object.

4.1 Getting the member of a dict object

import inspect

objects = {
    "id":"123",
    "name":"chandra"
}

print(inspect.getmembers(objects))

Output:

[('__class__', <class 'dict'>), ('__contains__', <built-in method __contains__ of dict object at 0x10f596288>),
('__delattr__', <method-wrapper '__delattr__' of dict object at 0x10f596288>), ('__delitem__', <method-wrapper '__delitem__' of dict object at 0x10f596288>),
('__dir__', <built-in method __dir__ of dict object at 0x10f596288>),
('__doc__', "dict() -> new empty dictionary\ndict(mapping) -> new dictionary initialized from a mapping object's\n    " \
        "(key, value) pairs\ndict(iterable) -> new dictionary initialized as if via:\n    d = {}\n    for k, v in iterable:\n       " \
        " d[k] = v\ndict(**kwargs) -> new dictionary initialized with the name=value pairs\n    " \
        "in the keyword argument list.  For example:  dict(one=1, two=2)"), ('__eq__', <method-wrapper '__eq__' of dict object at 0x10f596288>),
('__format__', <built-in method __format__ of dict object at 0x10f596288>), ('__ge__', <method-wrapper '__ge__' of dict object at 0x10f596288>),
('__getattribute__', <method-wrapper '__getattribute__' of dict object at 0x10f596288>), ('__getitem__', <built-in method __getitem__ of dict object at 0x10f596288>),
('__gt__', <method-wrapper '__gt__' of dict object at 0x10f596288>), ('__hash__', None), ('__init__', <method-wrapper '__init__' of dict object at 0x10f596288>),
('__init_subclass__', <built-in method __init_subclass__ of type object at 0x10f33d120>), ('__iter__', <method-wrapper '__iter__' of dict object at 0x10f596288>),
('__le__', <method-wrapper '__le__' of dict object at 0x10f596288>), ('__len__', <method-wrapper '__len__' of dict object at 0x10f596288>),
('__lt__', <method-wrapper '__lt__' of dict object at 0x10f596288>), ('__ne__', <method-wrapper '__ne__' of dict object at 0x10f596288>),
('__new__', <built-in method __new__ of type object at 0x10f33d120>), ('__reduce__', <built-in method __reduce__ of dict object at 0x10f596288>),
('__reduce_ex__', <built-in method __reduce_ex__ of dict object at 0x10f596288>), ('__repr__', <method-wrapper '__repr__' of dict object at 0x10f596288>),
('__setattr__', <method-wrapper '__setattr__' of dict object at 0x10f596288>), ('__setitem__', <method-wrapper '__setitem__' of dict object at 0x10f596288>),
('__sizeof__', <built-in method __sizeof__ of dict object at 0x10f596288>), ('__str__', <method-wrapper '__str__' of dict object at 0x10f596288>),
('__subclasshook__', <built-in method __subclasshook__ of type object at 0x10f33d120>), ('clear', <built-in method clear of dict object at 0x10f596288>),
('copy', <built-in method copy of dict object at 0x10f596288>), ('fromkeys', <built-in method fromkeys of type object at 0x10f33d120>),
('get', <built-in method get of dict object at 0x10f596288>), ('items', <built-in method items of dict object at 0x10f596288>),
('keys', <built-in method keys of dict object at 0x10f596288>), ('pop', <built-in method pop of dict object at 0x10f596288>),
('popitem', <built-in method popitem of dict object at 0x10f596288>), ('setdefault', <built-in method setdefault of dict object at 0x10f596288>),
('update', <built-in method update of dict object at 0x10f596288>), ('values', <built-in method values of dict object at 0x10f596288>)]

4.2 Getting the dict documentation

import inspect

print(inspect.getdoc({}))

Output:

dict() -> new empty dictionary
dict(mapping) -> new dictionary initialized from a mapping object's
    (key, value) pairs
dict(iterable) -> new dictionary initialized as if via:
    d = {}
    for k, v in iterable:
        d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
    in the keyword argument list.  For example:  dict(one=1, two=2)

References:

Happy Learning 🙂