【发布时间】:2020-10-29 21:51:16
【问题描述】:
这个问题是the question I asked here 的后续问题,总结起来是:
“在python中我如何从文本文件params.txt中读取参数,创建变量并为它们分配文件中的值?文件的内容是(请忽略自动语法突出显示,@987654325 @实际上是一个纯文本文件):
Lx = 512 Ly = 512
g = 400
================ Dissipation =====================
nupower = 8 nu = 0
...[etc]
并且我希望我的 python 脚本能够读取该文件,以便将 Lx、Ly、g、nupower、nu 等用作变量(不是字典中的键),并在 params.txt 中给出适当的值。顺便说一句,我是 python 新手。”
在帮助下,我想出了以下使用 exec() 的解决方案:
with open('params.txt', 'r') as infile:
for line in infile:
splitline = line.strip().split(' ')
for i, word in enumerate(splitline):
if word == '=':
exec(splitline[i-1] + splitline[i] + splitline[i+1])
这行得通,例如print(Lx) 按预期返回 512。
我的问题是:
(1) 这种方法安全吗?大多数提到exec() 函数的问题的答案都包含有关其使用的可怕警告,并暗示除非您真的知道自己在做什么,否则不应使用它。如前所述,我是新手,所以我真的不知道自己在做什么,所以我想检查一下我不会用这个解决方案给自己带来问题。脚本的其余部分使用从此文件中读取的变量和其他文件中的数据进行一些基本分析和绘图。
(2) 如果我想将上面的代码封装在一个函数中,例如read_params(),只是将最后一行更改为exec(splitline[i-1] + splitline[i] + splitline[i+1], globals()) 的问题吗?我知道这会导致 exec() 在全局命名空间中进行分配。我不明白这是否安全,如果不安全,为什么不。 (见上文关于如何成为新手!)
【问题讨论】:
-
使用
exec()通常被认为是不安全的(潜在的安全隐患取决于输入的来源)。动态创建变量是一种糟糕的 Python 编程实践——尽管它是可能的。见How do I create variable variables?。 -
我建议你使用 Python 的 configparser 模块来做你想做的事。
-
感谢 martineau 和 GordonAitchJay,我现在了解了安全风险(在这种情况下我并不担心,因为这些代码都没有面向外界)。但是除了安全性之外,如果我像这样使用
exec()声明变量,是否存在与 python 如何跟踪变量、垃圾收集、堆栈的不当使用等有关的任何“代码安全”问题? -
我不知道。