运行字符串中包含的 Python 代码
我正在使用 pygame 和 box2d 编写一个游戏引擎,在角色生成器中,我希望能够编写将在 keydown 事件上执行的代码。
我的计划是在字符生成器中拥有一个文本编辑器,让您编写类似于以下内容的代码:
if key == K_a:
## Move left
pass
elif key == K_d:
## Move right
pass
我将以字符串形式检索文本编辑器的内容,并且我希望代码在该字符方法中的方法中运行:
def keydown(self, key):
## Run code from text editor
最好的方法是什么?
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
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
What's the best way to do that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以使用
eval(string)
方法来做这个。定义
eval(code, globals=None, locals=None)
该代码只是标准的 Python 代码 - 这意味着它仍然需要正确缩进。
全局变量可以定义自定义的
__builtins__
,这对于安全目的可能很有用。示例
将
hello
打印到控制台。 您还可以指定要使用的代码的本地和全局变量:安全问题
不过要小心。 任何用户输入都会被执行。 考虑一下:
有很多方法可以解决这个问题。 最简单的方法是执行以下操作:
这将引发异常,而不是擦除硬盘驱动器。 虽然您的程序是桌面程序,但如果人们重新分发脚本,这可能会成为问题,我想这是有意的。
奇怪的例子
下面是一个相当奇怪地使用
eval
的例子:它在 eval 行上的作用是:
contrivedExample
)。 消费者现在可以调用contrivedExample.hello()
。)hi
定义为指向hello
失败 事实
证明(感谢评论者!)您实际上需要使用
exec
语句。 大哎呀。 修改后的示例如下:exec
定义(这看起来很熟悉!)
Exec 是一条语句:
exec“code”[在范围内]
其中,scope 是局部变量和全局变量的字典。 如果未指定,它将在当前范围内执行。
该代码只是标准的 Python 代码 - 这意味着它仍然需要正确缩进。
exec
示例将
hello
打印到控制台。 您还可以指定要使用的代码的本地和全局变量:exec
安全问题不过要小心。 任何用户输入都会被执行。 考虑:
Print 语句
正如评论者所指出的,
print
是 3.0 之前的所有 Python 版本中的语句。 在 2.6 中,可以通过键入from __future__ import print_statement
来更改行为。 否则,使用:而不是:
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
Would print
hello
to the console. You can also specify local and global variables for the code to use:Security Concerns
Be careful, though. Any user input will be executed. Consider:
There are a number of ways around that. The easiest is to do something like:
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:What this does on the eval line is:
contrivedExample
to the script). The consumer can callcontrivedExample.hello()
now.)hi
as pointing tohello
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
ExampleWould print
hello
to the console. You can also specify local and global variables for the code to use:exec
Security ConcernsBe careful, though. Any user input will be executed. Consider:
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 typingfrom __future__ import print_statement
. Otherwise, use:Instead of :
正如其他人所指出的,您可以将文本加载到字符串中并使用
exec "codestring"
。 如果已包含在文件中,则使用 execfile 将避免加载它。一个性能说明:您应该避免多次执行代码,因为解析和编译 python 源代码是一个缓慢的过程。 IE。 没有:
您可以通过将源代码编译为代码对象(使用
compile()
和 exec 来改进这一点,或者更好的是,通过构造一个您保留的函数,并且只构建要么要求用户编写“def my_handler(args...)”,要么自己添加它,然后执行以下操作:
As others have pointed out, you can load the text into a string and use
exec "codestring"
. If contained in a file already, using execfile will avoid having to load it.One performance note: You should avoid execing the code multiple times, as parsing and compiling the python source is a slow process. ie. don't have:
You can improve this a little by compiling the source into a code object (with
compile()
and exec that, or better, by constructing a function that you keep around, and only build once. Either require the user to write "def my_handler(args...)", or prepend it yourself, and do something like:Then later:
您可以使用
eval()
You can use
eval()
评估或执行。 在编程之前你一定应该阅读Python库参考。
eval or exec. You should definitely read Python library reference before programming.