Running Python code contained in a string

前端 未结 4 1493
终归单人心
终归单人心 2020-12-03 12:32

I\'m writing a game engine using pygame and box2d, and in the character builder, I want to be able to write the code that will be executed on keydown events.

My plan

4条回答
  •  有刺的猬
    2020-12-03 12:50

    You can use the eval(string) method to do this.

    Definition

    eval(code, globals=None, locals=None)
    The code is just standard Python code - this means that it still needs to be properly indented.

    The globals can have a custom __builtins__ defined, which could be useful for security purposes.

    Example

    eval("print('Hello')")
    

    Would print hello to the console. You can also specify local and global variables for the code to use:

    eval("print('Hello, %s'%name)", {}, {'name':'person-b'})
    

    Security Concerns

    Be careful, though. Any user input will be executed. Consider:

    eval("import os;os.system('sudo rm -rf /')")
    

    There are a number of ways around that. The easiest is to do something like:

    eval("import os;...", {'os':None})
    

    Which will throw an exception, rather than erasing your hard drive. While your program is desktop, this could be a problem if people redistributed scripts, which I imagine is intended.

    Strange Example

    Here's an example of using eval rather strangely:

    def hello() : print('Hello')
    def world() : print('world')
    CURRENT_MOOD = 'happy'
    
    eval(get_code(), {'contrivedExample':__main__}, {'hi':hello}.update(locals()))
    

    What this does on the eval line is:

    1. Gives the current module another name (it becomes contrivedExample to the script). The consumer can call contrivedExample.hello() now.)
    2. It defines hi as pointing to hello
    3. It combined that dictionary with the list of current globals in the executing module.

    FAIL

    It turns out (thanks commenters!) that you actually need to use the exec statement. Big oops. The revised examples are as follows:


    exec Definition

    (This looks familiar!) Exec is a statement:
    exec "code" [in scope] Where scope is a dictionary of both local and global variables. If this is not specified, it executes in the current scope.

    The code is just standard Python code - this means that it still needs to be properly indented.

    exec Example

    exec "print('hello')"
    

    Would print hello to the console. You can also specify local and global variables for the code to use:

    eval "print('hello, '+name)" in {'name':'person-b'}
    

    exec Security Concerns

    Be careful, though. Any user input will be executed. Consider:

    exec "import os;os.system('sudo rm -rf /')"
    

    Print Statement

    As also noted by commenters, print is a statement in all versions of Python prior to 3.0. In 2.6, the behaviour can be changed by typing from __future__ import print_statement. Otherwise, use:

    print "hello"
    

    Instead of :

    print("hello")
    

提交回复
热议问题