4.5. Debugging Introspection — Python
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.5.1. Introspecting Types
4.5.2. id()
id('hello') # 4596416368 id('hello') # 4592969392
name = 'hello' id(name) # 4596353264 id(name) # 4596353264
id('hello') # 4466061520 id(str) # 4306722176
4.5.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.5.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.5.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.5.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.5.7. Introspecting Objects
4.5.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.5.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.5.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.5.11. hasattr(), getattr(), setattr()
class User: 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'Hello {firstname} {lastname}' alice = User(firstname='Alice', lastname='Apricot') print(alice) # Hello Alice
4.5.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.5.13. Introspecting Docstrings
4.5.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.5.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.5.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))