本文介绍了运行字符串中包含的Python代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用pygame和box2d编写一个游戏引擎,并且在角色生成器中,我希望能够编写将在按键事件中执行的代码。

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 was to have a text editor in the character builder that let you write code similar to:

if key == K_a:
    ## Move left
    pass
elif key == K_d:
    ## Move right
    pass

我将以字符串形式检索文本编辑器的内容,并且我希望代码在此Character方法中的方法中运行:

I will retrieve the contents of the text editor as a string, and I want the code to be run in a method in this method of Character:

def keydown(self, key):
    ## Run code from text editor

最好的方法是什么?

推荐答案

您可以使用方法来执行此操作。

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

eval(代码,globals = None,locals = None)

该代码只是标准的Python代码-这意味着仍然需要适当缩进。

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

全局变量可以定义一个自定义的 __ builtins __ ,这对安全性很有用。

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

eval("print('Hello')")

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.

以下是使用 eval 有点奇怪:

def hello() : print('Hello')
def world() : print('world')
CURRENT_MOOD = 'happy'

eval(get_code(), {'contrivedExample':__main__}, {'hi':hello}.update(locals()))

在评估行中的作用是:


  1. 为当前模块提供另一个名称(该名称变为脚本的 contrivedExample )。消费者现在可以调用 contrivedExample.hello()。)

  2. 它定义了 hi 指向 hello

  3. 它将字典与执行模块中当前全局变量的列表结合在一起。

  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.



失败



事实证明(感谢评论者!)您实际上需要使用 exec 语句。哎呀修改后的示例如下:

FAIL

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

(看起来很熟悉!)
Exec是一条语句:

exec code [作用域]
其中scope是局部变量和全局变量的字典。如果未指定,则在当前范围内执行。

(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.

该代码只是标准的Python代码-这意味着仍需要适当缩进。

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

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 安全问题



请注意。任何用户输入都将被执行。考虑:

exec Security Concerns

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

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






打印对帐单



正如评论者所指出的那样, print 是3.0之前的所有Python版本中的声明。在2.6中,可以通过在__future__ import print_statement 中键入来更改行为。否则,使用:


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"

而不是:

print("hello")

这篇关于运行字符串中包含的Python代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 09:59