我正在写使用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
什么是做到这一点的最好方法是什么?
你可以用eval(string)
方法来做到这一点。
定义
eval(code, globals=None, locals=None)
该代码只是标准的Python代码 - 这意味着它仍然需要适当缩进。
全局变量可以有一个自定义__builtins__
定义,这可能是出于安全目的。
例
eval("print('Hello')")
将打印hello
到控制台。 你也可以指定代码,使用局部和全局变量:
eval("print('Hello, %s'%name)", {}, {'name':'person-b'})
安全问题
要小心,虽然。 任何用户输入将被执行。 考虑:
eval("import os;os.system('sudo rm -rf /')")
有许多的周围方式。 最简单的是做这样的事情:
eval("import os;...", {'os':None})
这将抛出一个异常,而不是删除你的硬盘。 当你的程序是桌面,这可能是一个问题,如果人们重新分配脚本,我想象意。
奇怪的示例
下面是使用的例子eval
,而奇怪的是:
def hello() : print('Hello')
def world() : print('world')
CURRENT_MOOD = 'happy'
eval(get_code(), {'contrivedExample':__main__}, {'hi':hello}.update(locals()))
这里做的事情就行EVAL是:
- 给出当前模块的另一个名称(变成
contrivedExample
到脚本)。 消费者可以拨打contrivedExample.hello()
了。) - 它定义了
hi
为指向hello
- 它结合执行模块在当前全局的列表词典。
失败
事实证明(感谢提意见!),你实际上需要使用exec
语句。 大哎呀。 修改后的例子如下:
exec
定义
(这看起来很熟悉!)Exec在一份声明:
exec "code" [in scope]
凡范围是局部和全局变量的字典。 如果没有指定,它执行在当前范围。
该代码只是标准的Python代码 - 这意味着它仍然需要适当缩进。
exec
例
exec "print('hello')"
将打印hello
到控制台。 你也可以指定代码,使用局部和全局变量:
eval "print('hello, '+name)" in {'name':'person-b'}
exec
安全问题
要小心,虽然。 任何用户输入将被执行。 考虑:
exec "import os;os.system('sudo rm -rf /')"
print语句
亦如评论者所指出的, print
是在之前3.0的Python的所有版本的声明。 在2.6中,行为可以通过键入来改变from __future__ import print_statement
。 否则,使用:
print "hello"
代替 :
print("hello")
正如其他人所指出的那样,你可以加载文本字符串并使用exec "codestring"
。 如果文件中包含的已使用的execfile将避免加载它。
一个性能注意:应避免代码多次execing,为解析和编译Python源是一个缓慢的过程。 即。 没有:
def keydown(self, key):
exec user_code
您可以通过编译源转换成代码对象(改善这一点了compile()
和exec的是,或更好,通过构建你保持周围的功能,并且只有一次构建,要么需要用户编写“高清my_handler( ARGS ...)”,或自己预先准备它,这样做:
user_source = "def user_func(args):\n" + '\n'.join(" "+line for line in user_source.splitlines())
d={}
exec user_source in d
user_func = d['user_func']
再后来:
if key == K_a:
user_func(args)
EVAL或者exec。 你一定要读编程之前,Python库参考。