如何从字符串中运行大量的python代码?

时间:2013-04-14 08:59:32

标签: python url python-3.x exec dropbox

我需要能够从字符串中运行大量的python代码。简单地使用exec似乎不起作用,因为虽然代码在正常设置中完美运行,但这样做似乎会引发错误。我也不认为我可以像在互联网上托管一样导入它。这是代码:

import urllib.request

URL = "https://dl.dropboxusercontent.com/u/127476718/instructions.txt"  

def main():
    instructions = urllib.request.urlopen(URL)

    exec(instructions.read().decode())

if __name__ == "__main__":
    main()

这是我一直在犯的错误:

Traceback (most recent call last):
  File "C:\Python33\rc.py", line 12, in <module>
    main()
  File "C:\Python33\rc.py", line 9, in main
    exec(instructions.read().decode())
  File "<string>", line 144, in <module>
  File "<string>", line 120, in main
NameError: global name 'Player' is not defined

我正在尝试运行的代码可以在第一个代码段中的链接中找到。

如果您有任何问题我会回答。谢谢。

3 个答案:

答案 0 :(得分:3)

如果不指定全局变量,exec function(Python / bltinmodule.c)使用PyEval_GetGlobals()PyEval_GetLocals()。对于函数的执行框架,后者创建一个新的f_locals dict,它将成为编译代码中IMPORT_NAMESTORE_NAMELOAD_NAME操作的目标。

在Python的模块级别,正常的事态是globals() == locals()。在这种情况下,STORE_NAME正在使用模块的全局变量,这是模块中定义的函数将用作其全局命名空间。然而,对全局和局部使用单独的dicts显然打破了这个假设。

解决方案是手动提供globalsexec也将用作locals

def main():
    instructions = urllib.request.urlopen(URL)
    exec(instructions.read().decode(), globals())

您还可以使用已定义__name__的新词典:

def main():
    instructions = urllib.request.urlopen(URL)
    g = {'__name__': '__main__'}
    exec(instructions.read().decode(), g)

我在源代码中看到当前目录需要一个名为“pickup.wav”的声音文件,否则你只会收到另一个错误。

当然,关于使用exec这样的安全问题的评论仍然适用。我只是在解决名称空间技术问题。

答案 1 :(得分:1)

首先我想你可以尝试使用StringIO对象__import__。可能看起来像StackOverflow: Local Import Statements in Python

......但那不对。

然后我考虑使用imp模块,但这看起来没有用。

然后我看了一下:Alex Martelli对Use of Eval in Python的回答 - 并试图在一段愚蠢的代码上使用它。

我可以从中获取ast对象以及compile()的结果(尽管似乎只需拨打compile(some_string_containing_python_source, 'SomeName', 'exec')而无需通过ast.parse()如果您愿意,可以使用中间步骤。如果您希望在编译之前遍历生成的语法树,检查并可能修改节点,那么我将使用ast

最后,在执行命名空间中定义了函数,类或变量后,您似乎需要exec() compile()的结果。

答案 2 :(得分:0)

您可以使用pipe将所有字​​符串放入python的子进程中,并从中获取输出结果。

Google os.popensubprocess.Popen