Running Python code contained in a string
我正在使用pygame和box2d编写一个游戏引擎,在字符生成器中,我希望能够编写将在键控事件上执行的代码。
我的计划是在字符生成器中有一个文本编辑器,允许您编写类似以下内容的代码:
1 2 3 4 5 6 | if key == K_a: ## Move left pass elif key == K_d: ## Move right pass |
我将以字符串的形式检索文本编辑器的内容,并希望代码以这种字符方法的方法运行:
1 2 | def keydown(self, key): ## Run code from text editor |
最好的方法是什么?
您可以使用
Globals可以定义一个自定义的
1 | eval("print('Hello')") |
将
1 | eval("print('Hello, %s'%name)", {}, {'name':'person-b'}) |
安全问题
不过要小心。将执行任何用户输入。考虑:
1 | eval("import os;os.system('sudo rm -rf /')") |
有很多方法可以解决这个问题。最简单的做法是:
1 | eval("import os;...", {'os':None}) |
这将引发异常,而不是删除硬盘。虽然您的程序是桌面程序,但如果人们重新分配脚本,这可能是一个问题,我认为这是有意的。
奇怪的例子下面是一个使用
1 2 3 4 5 | def hello() : print('Hello') def world() : print('world') CURRENT_MOOD = 'happy' eval(get_code(), {'contrivedExample':__main__}, {'hi':hello}.update(locals())) |
这在评估线上的作用是:
失败
事实证明(感谢评论员!)您实际上需要使用
(这看起来很熟悉!)exec是一个语句:
代码只是标准的python代码——这意味着它仍然需要适当的缩进。
1 | exec"print('hello')" |
将
1 | eval"print('hello, '+name)" in {'name':'person-b'} |
不过要小心。将执行任何用户输入。考虑:
1 | exec"import os;os.system('sudo rm -rf /')" |
打印语句
正如评论者所指出的,
1 | print"hello" |
而不是:
1 | print("hello") |
正如其他人指出的,您可以将文本加载到字符串中并使用
一个性能注意事项:应该避免多次执行代码,因为解析和编译Python源代码的过程很慢。没有:
1 2 | def keydown(self, key): exec user_code |
您可以通过将源代码编译成代码对象(使用
1 2 3 4 5 6 7 | user_source ="def user_func(args): " + ' '.join(" "+line for line in user_source.splitlines()) d={} exec user_source in d user_func = d['user_func'] |
然后:
1 2 | if key == K_a: user_func(args) |
EVE或Excel。在编程之前,您一定要阅读python库参考。
您可以使用