问题描述
我正在使用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()))
在评估行中的作用是:
- 为当前模块提供另一个名称(该名称变为脚本的
contrivedExample
)。消费者现在可以调用contrivedExample.hello()
。) - 它定义了
hi
指向hello
- 它将字典与执行模块中当前全局变量的列表结合在一起。
- Gives the current module another name (it becomes
contrivedExample
to the script). The consumer can callcontrivedExample.hello()
now.) - It defines
hi
as pointing tohello
- 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代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!