从加载到模块中的字符串执行python代码

时间:2016-05-14 18:17:02

标签: python python-3.x module

我发现以下code snippet我似乎无法为我的场景(或任何场景)工作:

def load(code):
    # Delete all local variables
    globals()['code'] = code
    del locals()['code']

    # Run the code
    exec(globals()['code'])

    # Delete any global variables we've added
    del globals()['load']
    del globals()['code']

    # Copy k so we can use it
    if 'k' in locals():
        globals()['k'] = locals()['k']
        del locals()['k']

    # Copy the rest of the variables
    for k in locals().keys():
        globals()[k] = locals()[k]

我创建了一个名为“dynamic_module”的文件并将此代码放入其中,然后我尝试执行以下代码,该代码是我想要执行的一些动态创建的字符串的占位符。

import random
import datetime


class MyClass(object):
    def main(self, a, b):
        r = random.Random(datetime.datetime.now().microsecond)
        a = r.randint(a, b)
        return a

然后我尝试执行以下操作:

import dynamic_module
dynamic_module.load(code_string)
return_value = dynamic_module.MyClass().main(1,100)

当它运行时它应该返回1到100之间的随机数。但是,我似乎无法获得我发现即使是最简单的代码字符串也能工作的初始代码段。我认为我这样做的一部分困惑是我可能会误解全局和本地人的工作方式,因此如何正确解决我遇到的问题。我需要代码字符串来使用它自己的导入和变量,而不能访问运行它的那些代码字符串,这就是我经历这种有点过于复杂的方法的原因。

2 个答案:

答案 0 :(得分:2)

您不应该使用您找到的代码。它有几个大问题,尤其是大多数问题实际上并没有做任何事情(locals()是代理,从中删除对实际的本地没有影响,它会将你执行的任何代码放在同一个共享中全局等。)

使用该帖子中的接受的答案;重铸为一个变为:

的函数
import sys, imp

def load_module_from_string(code, name='dynamic_module')
    module = imp.new_module(name)
    exec(code, mymodule.__dict__)
    return module

然后使用它:

dynamic_module = load_module_from_string(code_string)
return_value = dynamic_module.MyClass().main(1, 100)

该函数生成一个新的,干净的模块对象。

答案 1 :(得分:0)

通常,这不是您应该如何动态导入和使用外部模块。您应该在函数中使用__import__来执行此操作。这是一个适合我的简单示例:

plt = __import__('matplotlib.pyplot', fromlist = ['plt'])
plt.plot(np.arange(5), np.arange(5))
plt.show()

我认为对于您的特定应用程序(从代码字符串加载),将动态生成的代码字符串保存到文件(在包含__init__.py文件的文件夹中)然后使用它来调用它会容易得多__import__。然后,您可以访问代码的所有变量和函数作为导入模块的一部分。

除非我遗漏了什么?