我想使用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,任何一个例子呢?
注意我不对安全性感兴趣。
答案 0 :(得分:1)
为什么不使用pickle
呢?您甚至可以在类上使用__getstate__
和__setstate__
方法来控制序列化和实例化的各个方面。看起来比做自己的eval()
事情要好得多。
否则,序列化格式中的值受控制程度如何?即也许你可以预测需要哪些模块。
答案 1 :(得分:1)
如果您坚持使用完整的Python(而不是像JSON或YAML那样更易于解析的东西)来处理数据,那么走AST看起来相当可行。您需要实现ast.NodeVisitor并跟踪所访问的Attribute节点。