有没有推荐的方法从text(json)文件加载任意函数?

时间:2014-05-03 13:54:12

标签: python json lambda pandas

我正在编写一个便利库,并寻找从文本文件加载lambda函数的最佳实践。

  • 该库旨在以已知格式导入一个或多个数据集(例如,Facebook Insights),并将数据操作为Pandas数据帧,然后可以在IPython笔记本或网页中绘制。
  • 每个定义都包含函数(用于DataFrame.groupby()中的聚合以及与lambda一起使用的DataFrame.apply()函数)
  • 我目前已将规则硬编码为将每个文件操作为dict,但我想将这些文件抽象为一系列json文件,以便我可以更轻松地添加定义。

对于聚合方法,列表相当短,因此我可以轻松地列出if语句。但是,根据定义,apply lambda函数对每个定义都是定制的。这是一个示例,它需要几列来获得百分比:

lambda x: float(float(x[1]) / float(x[0])) * 100}

我知道eval方法,但这听起来不是很好的做法(因为我有一天会打开这个以供其他人使用,eval可能会被滥用)。类似的是jsonpickle库,但原则上也可以滥用。替代方案是固定的函数列表,但我没有看到这种类型的任意函数可以被制作成一个固定的列表。

有没有人有类似的经验并且能够提供最佳实践方法?

1 个答案:

答案 0 :(得分:4)

虽然eval可能是一个安全漏洞,但可以通过修改全局变量来限制它可用的内容:

>>> f = eval('lambda x: float(x)', {'__builtins__': None})
>>> f('1.1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <lambda>
NameError: global name 'float' is not defined

相反,传入一个字典,其中只包含您希望向定义函数的函数公开的函数:

safe_builtins = dict(
    __builtins__ = None,
    float = float,
    sum = sum,
    custom_func = ...
)

loaded_func = eval("lambda x: ...", safe_builtins)