在编写配置文件时使用 ConfigParser 而不是常规的 python.py 文件有啥好处?
Posted
技术标签:
【中文标题】在编写配置文件时使用 ConfigParser 而不是常规的 python.py 文件有啥好处?【英文标题】:What is the benefit of using the ConfigParser instead of a regular python.py file when writing configuration files?在编写配置文件时使用 ConfigParser 而不是常规的 python.py 文件有什么好处? 【发布时间】:2011-05-11 15:14:15 【问题描述】:我一直在使用 ConfigParser 模块来编写配置文件。然而,最近一个想法让我想到了;为什么不直接使用纯 Python 呢?以这个配置文件为例:
[parameters]
# Host
host = ***.com
port = 22
要将这些值读入我的代码,我会这样做
import ConfigParser
config = ConfigParser.SafeConfigParser()
config.read('host.cfg')
host = config.get('parameters', 'host')
port = config.get('parameters', 'port')
另一方面,如果我有这样的配置文件:
# Host
host = '***.com'
port = 22
在我的主代码中,我可以这样做:
from host_cfg import *
那么我从使用 ConfigParser 模块中获得了什么?每种方法的优缺点是什么?
【问题讨论】:
【参考方案1】:那么我从使用 ConfigParser 模块中获得了什么?
与 Windows .ini 文件的兼容性。让一些人开心。
每种方法的优缺点是什么?
ConfigParser 的语法有限,一些相对简单的东西变得非常做作。查看logging
的示例。
Python 语法更简单,也更容易使用。没有安全漏洞,因为当他们可以简单地破解您的源代码时,没有人会浪费时间破解配置文件。事实上,他们可以破解大部分内置的 Python 库。就此而言,他们可以自己编写 Python 解释器。
当您的应用程序源代码中的其他地方有很多更容易利用的漏洞时,没有人会浪费时间破解配置文件。
【讨论】:
【参考方案2】:ConfigParser 解析简单、扁平的配置数据。导入 python 模块会运行代码。对于配置文件,您需要数据,而不是代码。结案。
好的,更详细一点:代码可以做各种各样的事情,包括更容易破坏 - 特别是在由非程序员编辑时(尝试解释 .ini
修改者,例如他们必须使用匹配的引号并转义......) - 或导致命名空间与应用程序的其他部分发生冲突(尤其是如果您 import *
)。另请参阅rule of Least Power。
【讨论】:
@delnan 很好的解释,但你答案的最后一部分听起来你在嘲笑 OP 不知道答案(尽管我怀疑这就是你的意思)。我会为你的答案投票,并稍微修改一下它的语气。 @delnan +1。我的评论是在您编辑之后发布的,但在编辑之前提到了答案。 @Steven:我的语气仍然需要一些润色。 -1:“案件已结案。”远非真实。运行配置代码可以简化很多事情。可能“利用”您的配置的邪恶反社会者可以完全访问您的所有 Python 代码。为什么要停止捏造配置?为什么不直接掺假所有代码? @delnan:我没有将所有的 python 与 ini 进行比较。只是分配整数和字符串。这看起来就像 ini 文件一样简单。我声称 .ini 语法同样晦涩难懂。你有证据吗?我没有理由相信人们神奇地比 Python 赋值语句更了解 .ini。我认为这两种语法都或多或少同样充满了问题。这就是案件没有“结案”的原因。【参考方案3】:Python 文件方法的一个潜在“缺点”是您的用户可以将任意代码放入将在您的应用程序上下文中执行的文件中。正如 S. Lott 在 cmets 中对这个答案所指出的那样(当我的警告更加有力时),这通常不是问题,因为用户(或黑客)通常无论如何都可以访问您的整个源代码并且可以进行任何所需的更改。
但是,我当然可以想象这种方法可能会导致新的安全漏洞的情况,例如主脚本文件只能由系统管理员写入,而每个用户的配置文件是唯一可由系统管理员编辑的文件最终用户。除非您确定您的代码永远不会在这样的环境中运行,否则我不会推荐 Python 模块方法。 “不要执行用户给你的代码”被广泛认为是一种最佳做法是有充分理由的。
执行配置文件也会使处理错误成为问题。如果用户引入了语法错误,您会想要捕获它,您可以通过在 import
周围抛出 try
来轻松做到这一点,但错误之后不会执行任何操作。在配置文件中,通常解析将继续下一行,因此用户最多会错过一个设置,而不是(比如说)其中的一半。有一些方法可以让 Python 模块更像一个配置文件(例如,您可以将文件读取为文本和 exec()
每行),但如果您必须做任何工作,使用 @987654324 会变得更容易@。
尽管如此,如果您仍想在配置文件中使用 Python 语法,则可以使用 ast
模块(参见函数 literal_eval()
)。
【讨论】:
-1:“您的用户可以将任意代码放入将在您的应用程序上下文中执行的文件中”。一个愚蠢的考虑。用户拥有所有可用的 Python 代码。他们可以破解任何他们想要破解的 Python 代码。当记录由hashlib
散列的密码非常简单时,配置文件实际上并不是一个有用的目标。
我宁愿假设如果您要分发 Python 应用程序,您会使用 py2exe 或类似工具对其进行包装,从而使原始源文件的可访问性有所降低。但是,您的观点被采纳了。
@kindall: "用户最多会错过一个设置" 这有多好?这可能是致命的,实际上,它可能导致可怕的安全漏洞或更糟。如果配置错误,我宁愿没有任何工作,也不愿让一些部分配置做一些可怕的错误。我不敢相信你会吹捧这是一个“优势”。部分配置是个很严重的问题。
视情况而定。我可能更愿意尽可能多地获取,并尝试根据我能阅读的内容为缺失值提供安全的默认值,或者在我无法做到这一点时给出关于缺失内容的具体消息。我可以看到使用模块方法的方法,但似乎那样做会更有效,并且需要对***进行一些改造。
@kindall:“安全默认值”永远不是对语法错误的适当响应。语法错误可能出现在最重要的参数中,该参数将设置从无安全性覆盖为真正的安全性。由于语法错误而缺少一个参数是不可想象的。参数中的错误语法意味着应用程序不能(也不应该)使用“安全”默认值在受损模式下开始运行。它应该拒绝运行——即崩溃。这是唯一明智的回应,.ini 文件并不比其他格式好(也不差)。以上是关于在编写配置文件时使用 ConfigParser 而不是常规的 python.py 文件有啥好处?的主要内容,如果未能解决你的问题,请参考以下文章