存储 Python 程序设置的官方方式是啥?

Posted

技术标签:

【中文标题】存储 Python 程序设置的官方方式是啥?【英文标题】:What's the official way of storing settings for Python programs?存储 Python 程序设置的官方方式是什么? 【发布时间】:2010-11-01 05:30:47 【问题描述】:

Django 使用真正的 Python 文件进行设置,Trac 使用 .ini 文件,而其他一些软件使用 XML 文件来保存这些信息。

Guido 和/或 Python 社区对这些方法中的一种是否比另一种更有利?

【问题讨论】:

根据***,“ini”文件在现在已弃用的 Windows 中占主导地位。所以 IMO,你应该跳过那个选择。 来自微软:Why are INI files deprecated in favor of the registry? 上面的链接已经烂了。 Microsoft 的新链接:Why are INI files deprecated in favor of the registry?2007 年 11 月 26 日 【参考方案1】:

取决于主要的目标受众。

如果是程序员随便改文件,就用settings.py之类的python文件

如果是最终用户,请考虑 ini 文件。

【讨论】:

典型的settings.py 文件是什么样的? 我认为他指的是 Django settings.py 文件。它是一个有效的 Python 文件,其中包含字符串、元组、列表和其他变量的声明。 我同意第一部分,但如果最终用户需要更改它,ConfigParser 可以读取您的内容。【参考方案2】:

正如许多人所说,没有“官方”的方式。然而,有很多选择。今年有很多可用的选项a talk at PyCon。

【讨论】:

@mac,我找到了:blip.tv/pycon-us-videos-2009-2010-2011/… @utdemir - 谢谢,我用你的链接更新了原来的答案,删除了我原来的评论......【参考方案3】:

不知道这是否可以被认为是“官方的”,但它在标准库中:14.2. ConfigParser — Configuration file parser。

显然,这不是一个通用的解决方案。只需使用最适合任务的任何东西,没有任何必要的复杂性(尤其是图灵完备性!想想自动或 GUI 配置器)。

【讨论】:

json 也在标准库中,还有各种 xml 处理模块 当然 JSON 是标准的,但是这个模块被称为“配置文件解析器”是有原因的。我发现它非常适合阅读/写作,对于新手和非新手用户来说都很容易理解。 @SilentGhost JSON 格式不太适合人工编辑的配置文件。 --- 1. 不支持cmets。 2. 很多方括号和双引号可能会混淆人工编辑。【参考方案4】:

我使用架子(http://docs.python.org/library/shelve.html):

shelf = shelve.open(filename)
shelf["users"] = ["David", "Abraham"]
shelf.sync() # Save

【讨论】:

来自 docs,“因为 shelve 模块由 pickle 支持,所以从不受信任的来源加载货架是不安全的。与 pickle 一样,加载货架可以执行任意代码”。如果这个问题是为了指导新手,每个人都应该将他们指向 configparser 模块,否则指向 JSON 或自定义文件。 INI 文件部分比 JSON 更明确(可读),即使您美化它的代码。 [] 括号增加了一些粗体感,因此易于观看。【参考方案5】:

还有一个选择,PyQt。 Qt 有一种独立于平台的方式来使用 QSettings 类存储设置。在幕后,在 Windows 上它使用注册表,在 linux 中它将设置存储在隐藏的 conf 文件中。 QSettings 非常好用,而且非常简洁。

【讨论】:

【参考方案6】:

据我所知,没有幸运的解决方案。存储应用程序设置的方式没有对错之分,xml、json 或所有类型的文件都可以,只要您对它感到满意。对于python,我个人使用pypref,它非常简单、跨平台且直接。

pypref 非常有用,因为它可以存储静态和动态设置和首选项...

from pypref import Preferences

#  create singleton preferences instance
pref = Preferences(filename="preferences_test.py")

# create preferences dict
pdict = 'preference 1': 1, 12345: 'I am a number'

# set preferences. This would automatically create preferences_test.py 
# in your home directory. Go and check it.
pref.set_preferences(pdict)

# lets update the preferences. This would automatically update 
# preferences_test.py file, you can verify that. 
pref.update_preferences('preference 1': 2)

# lets get some preferences. This would return the value of the preference if
# it is defined or default value if it is not.
print pref.get('preference 1')

# In some cases we must use raw strings. This is most likely needed when
# working with paths in a windows systems or when a preference includes
# especial characters. That's how to do it ...
pref.update_preferences('my path': " r'C:\Users\Me\Desktop' ")

# Sometimes preferences to change dynamically or to be evaluated real time.
# This also can be done by using dynamic property. In this example password
# generator preference is set using uuid module. dynamic dictionary
# must include all modules name that must be imported upon evaluating
# a dynamic preference
pre = 'password generator': "str(uuid.uuid1())"
dyn = 'password generator': ['uuid',]
pref.update_preferences(preferences=pre, dynamic=dyn)

# lets pull 'password generator' preferences twice and notice how
# passwords are different at every pull
print pref.get('password generator')
print pref.get('password generator')

# those preferences can be accessed later. Let's simulate that by creating
# another preferences instances which will automatically detect the 
# existance of a preferences file and connect to it
newPref = Preferences(filename="preferences_test.py")

# let's print 'my path' preference
print newPref.get('my path')

【讨论】:

pypref 完全震撼。使用起来非常简单直接(它让我想起了 androidSharedPreferences,也许这就是原因)。祝贺你的出色工作! 很遗憾 Python 3 不支持【参考方案7】:

我不确定是否有“官方”方式(Python 禅宗中没有提到 :))- 我自己倾向于使用 Config Parser 模块,我认为您会发现这很常见。我更喜欢 python 文件方法,因为你可以写回它并根据需要动态重新加载。

【讨论】:

【参考方案8】:

这在很大程度上取决于您的配置有多复杂。如果您正在做一个简单的键值映射,并且您希望能够使用文本编辑器编辑设置,我认为 ConfigParser 是您的最佳选择。

如果您的设置很复杂并且包括列表和嵌套数据结构,我会使用 XML 或 JSON 并创建一个配置编辑器。

对于非常复杂的事情,最终用户不希望更改太多设置,或者更受信任,只需创建一组 Python 类并评估 Python 脚本以获取配置。

【讨论】:

【参考方案9】:

使用json 模块是最简单的方法之一。 将文件保存在config.json 中,详细信息如下所示。

在json文件中保存数据:



    "john"  : 
        "number" : "948075049" , 
        "password":"thisisit" 
        

从 json 文件中读取:

import json

#open the config.json file 

with open('config.json') as f:
    mydata = json.load(f) ; 

#Now mydata is a python dictionary 

print("username is " , mydata.get('john').get('number') , " password is " , mydata.get('john').get('password')) ;

【讨论】:

请注意,mydata.get('john').get('number') 不是一个好的代码。如果数据中没有john 键,则mydata.get('john') 将返回None.get('number') 将引发异常。使用.get 假设您想优雅地处理丢失的数据;所以最好这样做:mydata.get('john', ).get('number') - 这不会导致异常,除非mydata 本身不是dict【参考方案10】:

对于我喜欢使用操作系统环境变量的 Web 应用程序:os.environ.get('CONFIG_OPTION')

这对于部署之间不同的设置特别有效。您可以在此处阅读有关使用 env vars 背后原理的更多信息:http://www.12factor.net/config

当然,这仅适用于只读值,因为对环境的更改通常不是持久的。但如果您不需要写权限,它们是一个非常好的解决方案。

【讨论】:

不错,但是当有很多变量要设置时,使用 Django 方式可能会更方便:将其存储到文件中并根据单个环境变量设置不同的文件(在 django 中,DJANGO_SETTINGS_MODULE )。这样你也可以拥有动态和可写的值。 如果您正在使用这种方法,那么您可能还想看看github.com/theskumar/python-dotenv【参考方案11】:

不是官方的,但这种方式适用于我所有的 Python 项目。

pip install python-settings

这里的文档:https://github.com/charlsagente/python-settings

您需要一个包含所有已定义常量的 settings.py 文件,例如:

# settings.py

DATABASE_HOST = '10.0.0.1'

然后您需要设置一个环境变量(导出 SETTINGS_MODULE=settings)或手动调用配置方法:

# something_else.py

from python_settings import settings
from . import settings as my_local_settings

settings.configure(my_local_settings) # configure() receives a python module

该实用程序还支持对重负载对象进行延迟初始化,因此当您运行 python 项目时,它加载速度更快,因为它只在需要时评估设置变量

# settings.py

from python_settings import LazySetting
from my_awesome_library import HeavyInitializationClass # Heavy to initialize object

LAZY_INITIALIZATION = LazySetting(HeavyInitializationClass, "127.0.0.1:4222") 
# LazySetting(Class, *args, **kwargs)

只需配置一次,然后在需要的地方调用您的变量:

# my_awesome_file.py

from python_settings import settings 

print(settings.DATABASE_HOST) # Will print '10.0.0.1'

【讨论】:

这个库使用 Python 文件来存储配置。此选项具有巨大的安全缺陷,因为配置文件可能包含任何可执行代码 - 可能是恶意的或无意中以错误的方式失败。【参考方案12】:

这样更方便。没有官方说法。但是使用 XML 文件是有意义的,因为它们可以被各种其他应用程序/库操作。

【讨论】:

json、ini文件等也可以这样说 @Darren:如果您使用的是 Python 2.5 或更高版本,则不正确(因为 ElementTree) @becomingGuru:XML 设计目标 6:“XML 文档应该易于阅读且相当清晰。” @S. Lott - 当然他们应该这样做,但这并不意味着他们真的是。您必须承认编辑 ini 或属性文件比编辑 xml 文档要容易得多。 @Shane C. Mason:人类应该读/写 XML。实际上,这确实很难,因此我很少使用 XML。我使用 JSON 或 CSV 文件——更容易编辑。但是@becomingGuru 的评论——在狭义的技术意义上——是不正确的。【参考方案13】:

为什么Guido会祝福他范围之外的东西?不,没有什么特别的祝福。

【讨论】:

赞成,因为您实际上回答了 OP 的问题(“没有什么特别的祝福”)。反对意见可能来自您答案的第一部分:让社区共享“最佳实践”确实有助于开始使用新语言/新项目... 我理解 Guido 的裁决在核心、stdlib 开发等方面的作用,但问题是关于基本使用,很难定义好的实践。

以上是关于存储 Python 程序设置的官方方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 中存储网站设置的最佳方式是啥? [关闭]

为有关餐厅的程序存储数据的最佳方式是啥?

OS X 应用程序。存储数据的最佳方式是啥?

在 Rails 中存储应用程序特定配置的最佳方式是啥?

在 iOS 应用程序中本地存储数据的最佳方式是啥? [复制]

为 iOS/Android 应用程序存储敏感数据的最佳方式是啥?