【问题标题】:Python "safe" eval (string to bool/int/float/None/string)Python“安全”评估(字符串到 bool/int/float/None/string)
【发布时间】:2011-05-22 06:40:00
【问题描述】:

我正在制作一个进行一些数据处理的 web 应用程序,因此我经常发现自己将字符串(来自 URL 或文本文件)解析为 Python 值。

我使用的函数是“某种”更安全的 eval 版本(除非它无法读取字符串,它仍然是字符串):

def str_to_value(string):
    for atom in (True, False, None):
        if str(atom) == string:
            return atom
    else:
        try:
            return int(string)
        except ValueError:
            try:
                return float(string)
            except ValueError:
                return string

...但是,这对我来说似乎很丑陋。有更清洁的方法吗?我发现了一个类似这样的old discussion os,但我想知道是否没有一种快速简单的方法(比如我不知道的库函数,或者聪明的单线?)。

【问题讨论】:

  • 不,我认为如果你想允许这些类型中的任何一种,这可能就是这样做的方法。但这对我来说似乎很奇怪。你不知道输入是什么类型的吗?你怎么知道如何处理输入?
  • 这是不安全的,除非你相信string 是一个str(也不是一个子类)——否则,一个邪恶的人可以用一个恶意的__eq__ 方法编写一个类当您测试您的字符串是否看起来像 True 时会调用它。
  • Lennart:例如,我可以在通用 CsvToDict 函数中使用这种转换,然后在 ExpectKeysToBeInts(CsvToDict("ints_as_keys.csv")) 和 ExpectValuesToBeFloats(CsvToDict(" float_values.csv")) - 我宁愿我的 ExpectKeysToBeInts 和 ExpectValuesToBeFloats 保持简单,不必关心数据转换。
  • katrielalex:是的,我将所有数据都作为字符串获取(我认为如果我得到不受信任的 Python 对象,那么其他地方可能已经存在巨大的安全漏洞)。

标签: python parsing type-conversion


【解决方案1】:

ast.literal_eval()

>>> ast.literal_eval('{False: (1, 0x2), True: [3.14, 04, 0b101], None: ("6", u"7", r\'8\')}')
{False: (1, 2), True: [3.1400000000000001, 4, 5], None: ('6', u'7', '8')}

【讨论】:

  • 谢谢! Guido's Time Machine又来了!我将不得不深入研究 ast 库,它是最有可能包含有用内容的“通用”库之一(如 itertools、functools、collection ...)
  • 我刚刚意识到我过去创造了多少邪恶的肮脏黑客,应该使用它而不是普通的eval。哎哟。 :)
猜你喜欢
  • 2013-03-24
  • 2023-03-29
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 2020-04-20
  • 1970-01-01
  • 2011-03-31
相关资源
最近更新 更多