【问题标题】:Loading settings.py config file into a dict将 settings.py 配置文件加载到字典中
【发布时间】:2012-05-13 10:43:06
【问题描述】:

假设我有一个名为 settings.py 的文件,其内容如下:

{
    "translate_tabs_to_spaces": True,
    "word_wrap": "true",
    "font_face": "Monaco",
    "font_size": 14.0,
    "highlight_line": True,
    "ignored_packages":
    [
        ""
    ],
    "what": '''
            This is python file, not json
            '''
}

如何在我的主应用文件 app.py 中将其放入名为 settings 的字典中?

谢谢。

【问题讨论】:

  • 为什么不使用 JSON? Python 有一个 json 模块,可以非常容易地解码 JSON 数据。它还避免了加载未经验证的python代码的令人讨厌的副作用,在某些答案的cmet中已经提到。
  • @Michael 因为我想用 ''' ... '''
  • 你能在问题中添加一个例子吗?
  • 在三重引号字符串中,如果我使用 Python,我不需要转义任何内容,如果我想用大量“和”手动编写设置文件,我会弄乱 json在字符串文字中。如果我错了,请纠正我。
  • 在这种情况下,您可能希望将设置文件写入INI 文件并使用ConfigParser 加载它。恕我直言INI 文件更易于阅读。

标签: python configuration configuration-files


【解决方案1】:

您可以使用ast.literal_eval() 安全地执行此操作。

import ast

data="""\
{
    "translate_tabs_to_spaces": True,
    "word_wrap": "true",
    "font_face": "Monaco",
    "font_size": 14.0,
    "highlight_line": True,
    "ignored_packages":
    [
        ""
    ],
    "what": '''
            This is python file, not json
            '''
}\
"""

print(ast.literal_eval(data))

给我们:

{'what': '\n            This is python file, not json\n            ', 'font_size': 14.0, 'translate_tabs_to_spaces': True, 'font_face': 'Monaco', 'word_wrap': 'true', 'highlight_line': True, 'ignored_packages': ['']}

编辑:

鉴于提问者的新评论表明他希望能够在他的配置中使用 ...ast.literal_eval()适合,因为它不能处理椭圆。不太清楚这是否是他的意思,这仍然是对所提问题的一个很好的回答。

原来提问者在谈论三引号字符串,这是正确处理的。

【讨论】:

  • -1 不需要文字评估,只需导入模块并获得所有python免费赠品
  • 我认为您误解了这个问题。文件名是settings.py。这是一个python文件,听起来像是作者写的一个包的一部分。这不是来自未知用户的随机不受信任的文本。
  • 目的是为了改变设置 - 它是 Python 语法,所以它仍然是 .py 是有意义的。为什么要引入(不必要的)攻击向量风险 - 无论多么不可能,并强制改变所需的文件布局,但有一个既好的、简单的解决方案又不能做到这一点?
  • 对不起,按照这种偏执的逻辑,我们应该使用ast 来执行它可以处理的所有导入,而不是直接导入。这对我来说没有任何意义。如果有人可以访问settings.py,那么他们也可以访问源的其余部分。他们可以为所欲为; ast.literal_eval 那时不会阻止他们。
  • @Lattyware 我同意 senderie 的观点,如果攻击者可以破坏您的设置文件,那么您的整个源代码库也会受到破坏。
【解决方案2】:

在设置模块中为设置字典命名,然后将设置模块导入您的模块并将其加载到类似的变量中

import settings
your_settings = settings.settings_dict

【讨论】:

  • -1,这很危险 - 它可能包含恶意代码。它还需要更改数据文件。
  • 如果你使用的是设置模块,那么我猜它肯定是你写的
  • @Lattyware 真的,OP 并没有告诉 settings.py 是如何创建的,可能它只是 django 中使用的一个设置文件
  • 我并不是说这很有可能,但为什么要引入这种风险呢?如果用户盲目地复制/粘贴设置文件,为什么要让他们潜在地引入恶意内容。
  • @Lattyware 所以你认为 django 项目不应该使用 settings.py 吗?
【解决方案3】:

为什么不将这个字典命名为settings 而不仅仅是从 settings.py 导入它,例如

settings.py

settings = {} # fill with your data

这样使用

>>> from settings import settings
>>> print settings
{}

替代解决方案是在设置模块级别添加变量并直接使用它们,为什么需要字典?例如

settings.py

translate_tabs_to_spaces = True
# more settings

这样使用

>>> import settings
>>> settings.translate_tabs_to_spaces
True

【讨论】:

  • -1,这很危险 - 它可能包含恶意代码。它还需要更改数据文件。
  • @Lattyware 真的,OP 并没有告诉 settings.py 是如何创建的,可能它只是 django 中使用的一个设置文件
  • @Lattyware 我真的没有看到这种方法有什么危险。如果字典没有被命名为它的危险性较低?对我来说,这是正确的方法。谁在其中制作了一个带有 dict 的文件而不将其命名为变量?
  • @aschmid00 问题是您可以将任何代码放入此文件,如果您导入它,它将运行。至于谁将 dict 放入文件而不命名,好吧,有人编写设置文件。大多数设置文件不以settings = { ...开头。
  • @Lattyware 我认为您不使用正确模块的建议是错误的,我的建议一点也不危险,如果用户在线提交设置文件以运行,这可能是危险的,但如果这是只是一个包含在代码中的设置文件,它一点也不危险,使用 python 模块作为设置文件有很多优点,比如你可以拥有if/else、循环等
猜你喜欢
  • 2021-10-04
  • 2015-08-26
  • 1970-01-01
  • 1970-01-01
  • 2012-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多