4.6. Introspection

  • Introspection is the ability to determine the type of an object at runtime

  • Everything in Python is an object and we can examine those objects

  • Python ships with a few built-in functions and modules to help us

4.6.1. Introspecting Types

4.6.2. id()

id('Mark Watney')
# 4596416368
id('Mark Watney')
# 4592969392
name = 'Mark Watney'

id(name)
# 4596353264
id(name)
# 4596353264
id('Mark Watney')
# 4466061520
id(str)
# 4306722176

4.6.3. type()

type('')                            # <type 'str'>
type(str)                           # <class 'type'>

type([])                            # <type 'list'>
type(list)                          # <class 'type'>

type({})                            # <type 'dict'>
type(dict)                          # <type 'type'>

type(3)                             # <type 'int'>
type(int)                           # <class 'type'>

4.6.4. isinstance()

my_data = {}
isinstance(my_data, (set, dict))    # True
isinstance(my_data, dict)           # True
isinstance(my_data, set)            # False
my_data = {1}
isinstance(my_data, dict)           # False
isinstance(my_data, set)            # True
my_data = {1: 1}
isinstance(my_data, dict)           # True
isinstance(my_data, set)            # False

4.6.5. issubclass()

class Cosmonaut:
    pass

class GieroyCCCP(Cosmonaut):
    pass


issubclass(Cosmonaut, Cosmonaut)     # True
issubclass(Cosmonaut, GieroyCCCP)    # False
issubclass(GieroyCCCP, GieroyCCCP)   # True
issubclass(GieroyCCCP, Cosmonaut)    # True

4.6.6. callable()

class Car:
    def setName(self, name):
        self.name = name

def fun():
    pass

c = Car()

callable(fun)                       # True
callable(c.setName)                 # True
callable([])                        # False
callable(1)                         # False

4.6.7. Introspecting Objects

4.6.8. dir()

  • Returns a list of attributes and methods belonging to an object

class Server:
    """Connects to the server"""
    _connection = None

    def __init__(self, host, port):
        """Initializes object"""
        self.host = host
        self.port = port

    def login():
        """logs-in to the server"""

connection = Server(host='example.com', port=1337)

result = dir(connection)
print(result)
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__',
#  '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__',
# '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
# '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
# '_connection', 'host', 'login', 'port']

4.6.9. object.__dict__

  • Returns dynamic fields of an object

class Server:
    """Connects to the server"""
    _connection = None

    def __init__(self, host, port):
        """Initializes object"""
        self.host = host
        self.port = port

    def login():
        """logs-in to the server"""

connection = Server(host='example.com', port=1337)

connection.__dict__
# {'host': '127.0.0.1', 'port': 1337}

4.6.10. vars()

class Server:
    """Connects to the server"""
    _connection = None

    def __init__(self, host, port):
        """Initializes object"""
        self.host = host
        self.port = port

    def login():
        """logs-in to the server"""

connection = Server(host='example.com', port=1337)

vars(Server)
# {
#    '__module__': '__main__',
#    '__doc__': 'Connects to the server',
#    '_connection': None,
#    '__init__': <function Server.__init__ at 0x111f77488>,
#    'login': <function Server.login at 0x111f77268>,
#    '__dict__': <attribute '__dict__' of 'Server' objects>,
#    '__weakref__': <attribute '__weakref__' of 'Server' objects>
# }

4.6.11. hasattr(), getattr(), setattr()

class Astronaut:
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

    def __str__(self):
        if hasattr(self, 'firstname'):
            firstname = getattr(self, 'firstname')

        lastname = getattr(self, 'lastname', 'n/a')
        return f'My name... {firstname} {lastname}'


 jose = Astronaut(firstname='José', lastname='Jiménez')

 print(jose)
 # My name... José Jiménez

4.6.12. inspect module

The inspect module also provides several useful functions to get information about live objects. For example you can check the members of an object by running:

import inspect

inspect.getmembers(str)
# [('__add__', <slot wrapper '__add__' of ... ...

4.6.13. Introspecting Docstrings

4.6.14. help()

class Server:
    """Connects to the server"""
    _connection = None

    def __init__(self, host, port):
        """Initializes object"""
        self.host = host
        self.port = port

    def login():
        """logs-in to the server"""

connection = Server(host='example.com', port=1337)

help(connection)
# Help on Server in module __main__ object:
#
# class Server(builtins.object)
#  |  Server(host, port)
#  |
#  |  Connects to the server
#  |
#  |  Methods defined here:
#  |
#  |  __init__(self, host, port)
#  |      Initializes object
#  |
#  |  login()
#  |      logs-in to the server
#  |
#  |  ----------------------------------------------------------------------
#  |  Data descriptors defined here:
#  |
#  |  __dict__
#  |      dictionary for instance variables (if defined)
#  |
#  |  __weakref__
#  |      list of weak references to the object (if defined)

4.6.15. object.__doc__

class Server:
    """Connects to the server"""
    _connection = None

    def __init__(self, host, port):
        """Initializes object"""
        self.host = host
        self.port = port

    def login():
        """logs-in to the server"""

connection = Server(host='example.com', port=1337)

connection.login.__doc__
# 'logs-in to the server'

4.6.16. Examples

import settings
from django.db import models

for app in settings.INSTALLED_APPS:
    models_name = app + ".models"

    try:
        models_module = __import__(models_name, fromlist=["models"])
        attributes = dir(models_module)

        for attr in attributes:
            try:
                attrib = models_module.__getattribute__(attr)
                if issubclass(attrib, models.Model) and attrib.__module__== models_name:
                print(f'{models_name}.{attr}')
            except TypeError, e:
                pass
    except ImportError, e:
        pass
from django.contrib import admin
from . import models
import inspect

for name, obj in inspect.getmembers(models):
    if inspect.isclass(obj):
        admin.site.register(getattr(models, name))