【问题标题】:`ast.literal_eval` equivalent for custom class objects?自定义类对象的“ast.literal_eval”等价物?
【发布时间】:2017-07-22 20:49:11
【问题描述】:

ast.literal_eval 非常适合评估 python 的内置类型:

In [42]: import ast

In [43]: ast.literal_eval('[1, 2, 3, "4", None, (5, 4, 3)]')
Out[43]: [1, 2, 3, '4', None, (5, 4, 3)]

自定义类对象失败:

In [44]: class Foo():
    ...:     def __init__(self, val):
    ...:         self.val = val
    ...:  

In [45]: ast.literal_eval('[Foo(1), Foo(2), Foo(3)]')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-47-a3bd4f494d5d> in <module>()
----> 1 ast.literal_eval('[Foo(1), Foo(2), Foo(3)]')

但是,eval 工作正常:

In [46]: eval('[Foo(1), Foo(2), Foo(3)]')
Out[46]: 
[<__main__.Foo at 0x107e13940>,
 <__main__.Foo at 0x107e131d0>,
 <__main__.Foo at 0x107e13160>]

如何将ast.literal_eval 的安全性与eval 用于自定义对象的功能结合起来?

我查看了this,但这与已经存在的变量有关。

【问题讨论】:

  • 函数调用不是文字。文字是字符串文字整数文字TrueFalseNone列表文字元组字面量设置字面量字典字面量
  • 例如ast.literal_eval('dict()') 也失败了。因为您可以在代码中覆盖dict(..)。所有的调用——不管它们是否是内置的——都会失败。
  • @WillemVanOnsem 那么归根结底,没有解决方案?
  • 您可以构造一个自定义的ast 来允许某些事情。但我会使用白名单而不是黑名单。

标签: python


【解决方案1】:

如果你的数据是这样的 -

'["Foo(1)", "Foo(2)", "Foo(3)"]'

literal_eval 会起作用的。 因为它会认为 Foo(1) 和其他是字符串并且会识别它们。

'[Foo(1), Foo(2), Foo(3)]'

据我所知,这不能用作 literal_eval 中的参数。

来自docs

安全地评估包含 Python 文字或容器显示的表达式节点或字符串。提供的字符串或节点只能由以下 Python 文字结构组成:字符串、字节、数字、元组、列表、字典、集合、布尔值和无。

【讨论】:

    猜你喜欢
    • 2017-10-26
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多