从加载到modu的字符串执行python代码

2024-04-20 08:11:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我发现下面的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\u 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之间的随机数。然而,我似乎无法得到我发现的初始代码段,即使是最简单的代码字符串也能工作。我想我在做这件事时的困惑部分是我可能误解了全球人和本地人是如何工作的,因此也就误解了如何正确地解决我遇到的问题。我需要代码字符串使用它自己的导入和变量,而不能访问运行它的源代码和变量,这就是为什么我要使用这个有点过于复杂的方法


Tags: the字符串代码importdatetimedef场景code
2条回答

一般来说,这不是动态导入和使用外部模块的方式。您应该在函数中使用__import__来实现这一点。下面是一个对我有用的简单例子:

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

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

除非我遗漏了什么

你不应该使用你找到的代码。它有几个大问题,尤其是它实际上没有做任何事情(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)

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

相关问题 更多 >