Home > Blogs > REPResentation in Python

REPResentation in Python

By  Jun 28, 2008

Topics: Programming

For a language to be dynamic, it needs an eval() function of some sort. Getting from text to code and back again is easy in Python.

One of the small surprises I have encountered in Core Python is how Python has many similarities to JavaScript. Doug Crockford likes to say that JavaScript's eval() function is one of the misused features of the language. There is no doubt that this is true, but it's still a fun feature to hackers everywhere. So I was very interested to read all about this feature in Python.

The repr() function is a built-in-function that is in many ways the inverse of eval(). That is for many objects eval(repr(x)) == x is true. For example:

>>> data = {'port':80, 'secure':False}
>>> repr(data)
"{'port': 80, 'secure': False}"
>>> eval(repr(data)) == data

Here a Python dict was used. I was excited by this feature since it makes repr() a useful tool in conjunction with caching technologies. In particular, I thought that this might be useful to use with Google App Engine's Memcache API. It does indeed work pretty well for build in datastructures like dicts and lists. However, it does not work so well with classes:

>>> class Car():
...     def __init__(self, make,model):
...             self.make = make
...             self.model = model
>>> c = Car('VW', 'Passat')
>>> repr(c)
'<__main__.Car instance at 0x6d558>'
>>> eval(repr(c)) == c
Traceback (most recent call last):
  File "", line 1, in
  File "", line 1
    <__main__.Car instance at 0x6d558>
SyntaxError: invalid syntax

Ouch! Luckily Python handles this with a more powerful serialization modules, pickle. So repr() is good enough for built-in types, but pickle is good enough for everything.

>>> import pickle
>>> str = pickle.dumps(c)
>>> str

However, eval() does not work with pickle:

>>> eval(str)
Traceback (most recent call last):
  File "", line 1, in
  File "", line 2
SyntaxError: invalid syntax

Instead you have to use pickle.loads():

>>> c2 = pickle.loads(str)
>>> c.make == c2.make
>>> c.model == c2.model

You would think that given Python's differentiation between value and reference comparison, that c == c2, but nope:

>>> c == c2

Oh well. Back to repr(). The string form of dicts and lists also looks very close to JavaScript's object literals, i.e. JSON. Indeed, repr() can be used to create JSON ... sometimes. Not always.

>>> map = {}
>>> exotic = unicode('food')
>>> map['exotic'] = exotic
>>> repr(map)
"{'exotic': u'food'}"

For unicode strings, you will see the u prefix in the repr() output. That's not JSON! Of course there are plenty of third party libraries for converting between Python and JSON. For the Google App Engine app I am working on, I simply used simplejson, since it is part of Django and thus a built-in for GAE.