On Using eval() in Python

Originally posted on StackOverflow.

I have used eval() in the past (and still do from time-to-time) for massaging data during quick and dirty operations. It is part of the toolkit that can be used for getting a job done, but should NEVER be used for anything you plan to use in production such as any command-line tools or scripts, because of all the reasons mentioned in the other answers.

You cannot trust your users–ever–to do the right thing. In most cases they will, but you have to expect them to do all of the things you never thought of and find all of the bugs you never expected. This is precisely where eval() goes from being a tool to a liability.

A perfect example of this would be using Django, when constructing a QuerySet. The parameters passed to a query accepts keyword arguments, that look something like this:

results = Foo.objects.filter(whatever__contains='pizza')

If you’re programmatically assigning arguments, you might think to do something like this:

results = eval("Foo.objects.filter(%s__%s=%s)" % (field, matcher, value))

But there is always a better way that doesn’t use eval(), which is passing a dictionary by reference:

results = Foo.objects.filter( **{'%s__%s' % (field, matcher): value} ) 

By doing it this way, it’s not only faster performance-wise, but also safer and more Pythonic.

Moral of the story?

Use of eval() is ok for small tasks, tests, and truly temporary things, but bad for permanent usage because there is almost certainly always a better way to do it!

Leave a Reply

Your email address will not be published. Required fields are marked *