【问题标题】:Config file with a .py file带有 .py 文件的配置文件
【发布时间】:2017-04-17 06:33:09
【问题描述】:

有人告诉我这样做是一种不是很好的做法:

配置文件.py

SOUNDENABLED = 1
FILEPATH = 'D:\\TEMP\\hello.txt'

main.py

import configfile

if configfile.SOUNDENABLED == 1:
    ....

f = open(configfile.FILEPATH, 'a')
...

许多人使用 INI 文件通过ConfigParser 模块或iniparse 或其他类似模块进行本地配置这一事实证实了这一点。

问题:

为什么使用 INI 文件进行本地配置 + INI 解析器 Python 模块比仅导入包含正确配置值作为常量的 configfile.py 文件更好?

【问题讨论】:

  • 尝试将 configfile.py 中的扩展名 .py 更改为其他内容 - 您的代码将无法正常工作。

标签: python parsing configuration-files ini


【解决方案1】:

这里唯一需要担心的是.py 可以包含任意 Python 代码,因此它有可能以任意方式破坏您的程序。

如果您可以信任您的用户负责任地使用它,那么此设置没有任何问题。事实上,at one of my previous occupations, we were doing just that, without any problems that I'm aware of. 恰恰相反:它允许用户通过自动生成重复部分和导入其他配置文件来消除重复。

另一个问题是,如果您有很多文件,最好将配置文件与常规代码文件分开,以便用户知道他们应该能够编辑哪些文件(上面的链接也解决了这个问题)。

【讨论】:

    【解决方案2】:

    由于某些原因可能会更好

    1. 配置文件的唯一扩展名是py
    2. 除非您将__init__.py 放入此目录中,否则您不能在单独的目录中分发带有配置的程序
    3. 您程序的讨厌用户可以将任何 python 脚本放入配置中并做坏事。

    例如,YouCompleteMe 自动完成引擎将配置存储在 python 模块 .ycm_extra_conf.py 中。默认情况下,每次导入配置时,它都会询问您是否确定文件可以安全执行。

    1. 如何在不重新启动应用的情况下更改配置?

    通常,允许执行来自外部某处的代码是一个漏洞,可能导致非常严重的后果。

    但是,如果您不关心这些,例如,您正在开发仅在您的服务器上执行的 Web 应用程序,那么将配置放入 python 模块是一种可接受的做法。 Django 会这样做。

    【讨论】:

    • 谢谢。我不太同意 3. :Python 是解释型的,所以这意味着您可以访问所有源文件。那么如果一个讨厌的用户想放恶意代码,他不需要放configfile.py,他可以放main.py,你不这么认为吗?
    • @Basj 如果从其他地方加载配置文件会怎样,例如您并不真正信任的远程文件系统?
    【解决方案3】:

    这是一种完全可以接受的做法。使用这种方法的一些知名项目的例子是Djangogunicorn

    【讨论】:

    • 谢谢。您能否在 github 上添加一些相关文件的链接以供将来参考,以便我们可以看到这是一种可以接受的做法?
    • 我已经链接到文档,这两个文档都明确声明设置是一个普通的 Python 文件。
    • 谢谢。他们如何才能 1) 从另一个目录导入相关的 config .py 文件? 2)确保部署新版本的Django时文件没有被删除?
    • 我不明白你的意思。设置在您自己的项目中,而不是在第三方库中;它们允许您定义您希望应用程序的配置方式。
    • 附带说明 django 用户不要直接导入设置文件。相反,他们导入 django.conf.settings,它导入用户设置文件,并围绕它构建一个代理对象,除其他外,允许定义默认值,而不必在设置文件中定义这些默认值,或者以其他方式由用户设置文件导入。 github.com/django/django/blob/master/django/conf/__init__.py
    【解决方案4】:

    导入模块会执行它包含的任何代码。没有什么可以限制您的 configfile.py 只包含定义。归根结底,这是安全问题和模糊错误的秘诀。此外,您必须使用 Python 的模块搜索路径来查找配置文件。如果您想将配置文件放在其他地方,或者存在名称冲突怎么办?

    【讨论】:

    • 谢谢。我不记得了,是不是没有办法从特定位置导入模块,比如 /boot/config.py ? (例如在树莓派上)
    • 是的,例如using importlib。但它不像import <module>open(<file path>) 那样简单。
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2019-06-26
    • 2023-03-30
    • 2022-01-14
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    • 2022-12-12
    相关资源
    最近更新 更多