Reflection in Python

Overview

Overview

What is Reflection?

In computer science, reflection is the ability of a computer program to examine, introspect, and modify its own structure and behaviour at runtime
Reflection in Wikipedia

Reflection vs Introspection?

Both are often used as synonymous, but a subtle difference exists:
Introspection refers to the ability of an object to examine itself.
Reflection includes the ability of an object to modify itself, not only to introspect.

dir() function

dir() function

Syntax


			dir([object])
		
Without arguments, return the list of names in the current local scope
If an argument is given, it attempt to return a list of valid attributes for that object
If the object has a method named __dir__(), this method will be called
dir() @python docs

Example


			class Person:
			  def __init__(self, name, age):
			    self.name = name
			    self.age = age

			maria = Person("Maria Popova", 25)

			print(dir(maria))
		

			['__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__', 'age', 'name']
		

We see Person object atributes, as well as these, inherited from the built-in object class

type() function

type() function

Syntax


			class type(object)
			class type(name, bases, dict)
		
With one argument, return the type of an object. The return value is a type object and generally the same object as returned by object.__class__.
With three arguments, return a new type object. This is essentially a dynamic form of the class statement.
type() @python docs

type(object) - example


			class Person:
			  def __init__(self, name, age):
			    self.name = name
			    self.age = age

			maria = Person("Maria Popova", 25)

			print(type(maria))
			# <class '__main__.Person'>
		

type(name, bases, dict) - example

Dynamically create Employee class


			Employee = type('Employee', (object,), dict())
			pesho = Employee()
			print(type(pesho))
			# <class '__main__.Employee'>
		

type(name, bases, dict) - example

Dynamically create Employee class, a subclass of Person


			Employee = type('Employee', (Person,), dict())
			pesho = Employee("Pesho", 30)
			print(type(pesho))
			# <class '__main__.Employee'>
		

id() function

id() function

Syntax


			id(object)
		
Return the “identity” of an object.
This is an integer which is guaranteed to be unique and constant for this object during its lifetime.
Two objects with non-overlapping lifetimes may have the same id() value.
In CPython, id() returns the address of the object in memory.

Example


			print(id(1))

			x = 1
			print(id(x))

			y=x
			print(id(y))

			#11065920
			#11065920
			#11065920
		

Attributes reflections

Attributes reflections

hasattr() - syntax


			hasattr(object, name)
		
Return True if the object has attribute with given name as string. False otherwise.

hasattr() - example


			class Person:
			  def __init__(self, name, age):
			    self.name = name
			    self.age = age


			maria = Person("Maria Popova", 25)

			print(hasattr(maria,"name"))
			print(hasattr(maria,"surname"))
			#True
			#False
		

getattr() - syntax


			getattr(object, name[, default])
		
Return the value of the named attribute of object
If the named attribute does not exist, default is returned if provided. Otherwise AttributeError is raised.

getattr() - example


			class Person:
			  def __init__(self, name, age):
			    self.name = name
			    self.age = age

			maria = Person("Maria Popova", 25)
			print(getattr(maria, "age"))
			# 25
		

setattr() - syntax


			setattr(object, name, value)
		
The arguments are an object, a string and an arbitrary value.
The string may name an existing attribute or a new attribute.
The function assigns the value to the attribute, provided the object allows it

setattr() - example


			class Person:
			  def __init__(self, name, age):
			    self.name = name
			    self.age = age

			maria = Person("Maria Popova", 25)

			setattr(maria, "surname", "Popova")
			print(getattr(maria, "surname"))
			# Popova
		

Object reflections

Object reflections

isinstance
issubclass

the inspect built-in module

the inspect built-in module

Overview

The inspect module provides several useful functions for:
type checking
getting source code
inspecting classes and functions
examining the interpreter stack

Docs: inspect — Inspect live objects

Example

Get a function name, within a function. Get the name of the object that called the function.


			import inspect

			def foo():
			  func_name = inspect.stack()[0][3]
			  caller_name = inspect.stack()[1][3]
			  print("I'm {}.\n{} called me!".format(func_name,caller_name))

			def bar(f):
			  f()

			bar(foo)
			# I'm foo.
			# bar called m
		

These slides are based on

customised version of

Hakimel's reveal.js

framework