存储 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
完全震撼。使用起来非常简单直接(它让我想起了 android 的 SharedPreferences
,也许这就是原因)。祝贺你的出色工作!
很遗憾 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 中存储网站设置的最佳方式是啥? [关闭]