Intro to Python Introspection and Dynamic Programming
by Phillip Watts
June 30, 2009
|
This week Phillip Watts introduces us to Python
introspection, which can help you write more efficient,
dynamic code.
|
Introduction
Introspection in humans is self examination. For
instance, if you try to understand why you like Rubik's Cube
but do not like Rembrandt, you are doing introspection.
Modern programming languages, including Python, have tools
which facillitate introspection. In the case of a
programming language, introspection is the ability of a
program to examine itself, or even the parent interpreter or
compiler.
The intended audience for this article is Python
programmers with some experience.
The hasattr function
Let us start with a simple but useful example of python
introspection. In this example we are using information
about classes, which is known to the class, to control the
behavior of our program:
class Device:
....
....
def getPowerReq(self):
return self.__powerReq
class DesktopPc(Device):
....
....
def getEths(self):
return self.__ethList
class Ipod(Device):
....
....
# this device has no eth adapters
def getToc(self):
return self.__Toc
devices = [DesktpPc(),Ipod(),...]
for device in devices:
if hasattr(device,'getEths'):
doSomeEthThings()
In this example we have defined a parent class, Device,
which has attributes, and some child classes which contain
their particular attributes. We have created a list of
instances of the devices. In the "for loop" we do something
only if the device has the attribute getEths. Therefore we
are using internal information about the program, i.e. its
classes, to control the program's behaviour.
By the way, this is sometimes referred to as "duck
typing". If it looks like a duck it must be a duck,
therefore you can treat it as a duck.
Before proceeding, we should note that the Python
language has much similarity to a Python program, in that,
everything in the language is an object. For now we will
limit the discussion to classes and instances of classes.
Just remember that Python has many built in classes, there
are hundreds in the "standard" libraries,and many thousands
which can be downloaded and all of the classes themselves
share some common properties.
The __dict__ built-in
In this next example, we make use of a property built in
to every class called __dict__ #!/usr/bin/env
python
class demo:
def __init__(self):
self.__propa = ''
self.__propb = ''
self.__propc = ''
self.__propd = ''
self.__prope = ''
self.__propf = ''
def clearVals(self):
dict = self.getVals()
for k in dict.keys():
dict[k] = None
def getVals(self):
return self.__dict__
if __name__ == '__main__':
# create two instances of demo
dem1 = demo(); dem2 = demo()
dem1.clearVals(); dem2.clearVals()
dict1 = dem1.getVals()
dict2 = dem2.getVals()
# now compare the two instances
for k in dict1.keys():
if dict1[k] != dict2[k]:
print dict[k], dict2[k]
The Demo class has only six properties, but imagine if it
had fifty. Our two methods, clearVals() and
getVals would require no more code than they do
now and would be no more susceptible to error. Also the code
in the main section, comparing the values between two
instances, would be the same. The built-in function
__dict__ returns a dictionary of all the
properties and their values.
Intro to Python Introspection and Dynamic Programming
The Type Function
|