Returning a value from code string

Kirk McDonald mooquack at suad.org
Fri Jan 27 23:33:53 EST 2006


Say I have a database containing chunks of Python code. I already have a 
way to easily load, edit, and save them. What is slightly baffling to me 
is how I can effectively pass this code some arguments, run it, and 
somehow get a return value.

(Acutally, in the process of writing this post, I figured out a pretty 
good way of doing it. Here's the rest of my post and the solution I came 
up with. Enjoy my thought process!)

Right now I'm thinking of just defining a standard function name, and 
using that as the entry/exit point for the DB-stored code. Is this 
reasonable? Is there some more Pythonic way?

I'll probably compile the code and store the bytecode to the database 
(in addition to the plain text) for faster execution time, as well. It 
shouldn't care whether the stored code is a string or a code object.

What if a stored chunk of code doesn't need to return anything? It would 
be more convenient to just execute the code without the standard 
function. Also, it'd be nice to wrap this in a class:

# module test.py
class Codeobj:
     def __init__(self, code=None):
         if code: self.code = code
         else: self.code = ""

     def __call__(self, args=None, **kwargs):
         # We can pass in a name/value dictionary
         if args: kwargs.update(args)
         exec self.code
         # We don't need a standard function if we're not returning
         # anything
         if locals().has_key('std_func_name'):
             return std_func_name(**kwargs)

if __name__ == "__main__":
     # Load code from the DB
     double = """\
def std_func_name(n):
     return n*2"""

     addthree = """\
def std_func_name(n):
     return n+3"""

     noreturn = "print 'arg = %s' % kwargs['arg']"

     a = Codeobj(double)
     b = Codeobj(addthree)
     c = Codeobj(noreturn)

     # Calling with name/value dictionary
     print a(args={'n':5})
     # Calling with specific named argument
     print b(n=4)
     c(arg='foo')
# EOF

$ python test.py
10
7
arg = foo

If I wanted to simplify the 'noreturn' example (well, if there were more 
lines of code this might make it simpler), I could have defined it like 
this:

     noreturn = """\
locals().update(kwargs)
print 'arg = %s' % arg"""

-Kirk McDonald



More information about the Python-list mailing list