在eval中自动导入所需的模块(...)

时间:2012-12-14 10:37:33

标签: python import eval

我想使用eval从文件加载对象。该对象被转储到文件中,因此它是一个有效的python表达式 - 所有类型都使用它们的fqdn,如下所示:

mod1.Class1(
    attr1=mod2.Class2(a=1,b=2),
    attr2=[1,2,3,4],
    attr3=mod1.submod1.Class3(),
)

当我将其提供给eval时,并非所有这些模块都在调用eval的范围内导入,因此我获得了顶级模块的NameError: name 'mod1' is not defined,或者,导入时,AttributeError: 'module' object has not attribute 'submod1'用于子模块。

有没有一种优雅的方式来处理它?我可以解析NameError,运行__import__并重新尝试eval,但我不知道如何从AttributeError中解决问题。

我可以将表达式提供给compile,走AST并导入必要的内容吗?从来没有使用AST,任何一个例子呢?

注意我对安全性感兴趣。

2 个答案:

答案 0 :(得分:1)

为什么不使用pickle呢?您甚至可以在类上使用__getstate____setstate__方法来控制序列化和实例化的各个方面。看起来比做自己的eval()事情要好得多。

否则,序列化格式中的值受控制程度如何?即也许你可以预测需要哪些模块。

答案 1 :(得分:1)

如果您坚持使用完整的Python(而不是像JSON或YAML那样更易于解析的东西)来处理数据,那么走AST看起来相当可行。您需要实现ast.NodeVisitor并跟踪所访问的Attribute节点。