How do I execute a string containing Python code in Python?

后端 未结 14 2406
一向
一向 2020-11-22 02:42

How do I execute a string containing Python code in Python?

相关标签:
14条回答
  • 2020-11-22 02:56

    In the example a string is executed as code using the exec function.

    import sys
    import StringIO
    
    # create file-like string to capture output
    codeOut = StringIO.StringIO()
    codeErr = StringIO.StringIO()
    
    code = """
    def f(x):
        x = x + 1
        return x
    
    print 'This is my output.'
    """
    
    # capture output and errors
    sys.stdout = codeOut
    sys.stderr = codeErr
    
    exec code
    
    # restore stdout and stderr
    sys.stdout = sys.__stdout__
    sys.stderr = sys.__stderr__
    
    print f(4)
    
    s = codeErr.getvalue()
    
    print "error:\n%s\n" % s
    
    s = codeOut.getvalue()
    
    print "output:\n%s" % s
    
    codeOut.close()
    codeErr.close()
    
    0 讨论(0)
  • 2020-11-22 02:57

    Use eval.

    0 讨论(0)
  • 2020-11-22 03:04

    Ok .. I know this isn't exactly an answer, but possibly a note for people looking at this as I was. I wanted to execute specific code for different users/customers but also wanted to avoid the exec/eval. I initially looked to storing the code in a database for each user and doing the above.

    I ended up creating the files on the file system within a 'customer_filters' folder and using the 'imp' module, if no filter applied for that customer, it just carried on

    import imp
    
    
    def get_customer_module(customerName='default', name='filter'):
        lm = None
        try:
            module_name = customerName+"_"+name;
            m = imp.find_module(module_name, ['customer_filters'])
            lm = imp.load_module(module_name, m[0], m[1], m[2])
        except:
            ''
            #ignore, if no module is found, 
        return lm
    
    m = get_customer_module(customerName, "filter")
    if m is not None:
        m.apply_address_filter(myobj)
    

    so customerName = "jj" would execute apply_address_filter from the customer_filters\jj_filter.py file

    0 讨论(0)
  • 2020-11-22 03:05

    eval and exec are the correct solution, and they can be used in a safer manner.

    As discussed in Python's reference manual and clearly explained in this tutorial, the eval and exec functions take two extra parameters that allow a user to specify what global and local functions and variables are available.

    For example:

    public_variable = 10
    
    private_variable = 2
    
    def public_function():
        return "public information"
    
    def private_function():
        return "super sensitive information"
    
    # make a list of safe functions
    safe_list = ['public_variable', 'public_function']
    safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
    # add any needed builtins back in
    safe_dict['len'] = len
    
    >>> eval("public_variable+2", {"__builtins__" : None }, safe_dict)
    12
    
    >>> eval("private_variable+2", {"__builtins__" : None }, safe_dict)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<string>", line 1, in <module>
    NameError: name 'private_variable' is not defined
    
    >>> exec("print \"'%s' has %i characters\" % (public_function(), len(public_function()))", {"__builtins__" : None}, safe_dict)
    'public information' has 18 characters
    
    >>> exec("print \"'%s' has %i characters\" % (private_function(), len(private_function()))", {"__builtins__" : None}, safe_dict)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<string>", line 1, in <module>
    NameError: name 'private_function' is not defined
    

    In essence you are defining the namespace in which the code will be executed.

    0 讨论(0)
  • 2020-11-22 03:06

    I tried quite a few things, but the only thing that work was the following:

    temp_dict = {}
    exec("temp_dict['val'] = 10") 
    print(temp_dict['val'])
    

    output:

    10

    0 讨论(0)
  • 2020-11-22 03:06

    The most logical solution would be to use the built-in eval() function .Another solution is to write that string to a temporary python file and execute it.

    0 讨论(0)
提交回复
热议问题