Python:你将如何保存一个简单的设置/配置文件?
Posted
技术标签:
【中文标题】Python:你将如何保存一个简单的设置/配置文件?【英文标题】:Python: How would you save a simple settings/config file? 【发布时间】:2013-10-05 08:51:15 【问题描述】:我不在乎是 JSON
、pickle
、YAML
还是其他。
我见过的所有其他实现都不向前兼容,所以如果我有一个配置文件,在代码中添加一个新键,然后加载该配置文件,它就会崩溃。
有什么简单的方法吗?
【问题讨论】:
我相信使用configparser
模块的 .ini
类格式应该可以满足您的需求。
有机会选择我的答案为正确吗?
【参考方案1】:
保存并加载字典。您将拥有任意键、值和任意数量的键、值对。
【讨论】:
我可以使用重构吗?【参考方案2】:如果您想使用类似 INI 文件的东西来保存设置,请考虑使用 configparser 从文本文件加载键值对,并且可以轻松地写回文件。
INI 文件格式为:
[Section]
key = value
key with spaces = somevalue
【讨论】:
【参考方案3】:python中的配置文件
根据所需的文件格式,有几种方法可以做到这一点。
ConfigParser [.ini 格式]
除非有令人信服的理由使用不同的格式,否则我会使用标准的 configparser 方法。
像这样写一个文件:
# python 2.x
# from ConfigParser import SafeConfigParser
# config = SafeConfigParser()
# python 3.x
from configparser import ConfigParser
config = ConfigParser()
config.read('config.ini')
config.add_section('main')
config.set('main', 'key1', 'value1')
config.set('main', 'key2', 'value2')
config.set('main', 'key3', 'value3')
with open('config.ini', 'w') as f:
config.write(f)
文件格式非常简单,部分用方括号标出:
[main]
key1 = value1
key2 = value2
key3 = value3
可以像这样从文件中提取值:
# python 2.x
# from ConfigParser import SafeConfigParser
# config = SafeConfigParser()
# python 3.x
from configparser import ConfigParser
config = ConfigParser()
config.read('config.ini')
print(config.get('main', 'key1')) # -> "value1"
print(config.get('main', 'key2')) # -> "value2"
print(config.get('main', 'key3')) # -> "value3"
# getfloat() raises an exception if the value is not a float
a_float = config.getfloat('main', 'a_float')
# getint() and getboolean() also do this for their respective types
an_int = config.getint('main', 'an_int')
JSON [.json 格式]
JSON 数据可能非常复杂,并且具有高度可移植性的优势。
将数据写入文件:
import json
config = "key1": "value1", "key2": "value2"
with open('config1.json', 'w') as f:
json.dump(config, f)
从文件中读取数据:
import json
with open('config.json', 'r') as f:
config = json.load(f)
#edit the data
config['key3'] = 'value3'
#write it back to the file
with open('config.json', 'w') as f:
json.dump(config, f)
YAML
in this answer 提供了一个基本的 YAML 示例。更多详情请访问the pyYAML website。
【讨论】:
在python 3中from configparser import ConfigParser
config = ConfigParser()
【参考方案4】:
ConfigParser 基本示例
文件可以这样加载和使用:
#!/usr/bin/env python
import ConfigParser
import io
# Load the configuration file
with open("config.yml") as f:
sample_config = f.read()
config = ConfigParser.RawConfigParser(allow_no_value=True)
config.readfp(io.BytesIO(sample_config))
# List all contents
print("List all contents")
for section in config.sections():
print("Section: %s" % section)
for options in config.options(section):
print("x %s:::%s:::%s" % (options,
config.get(section, options),
str(type(options))))
# Print some contents
print("\nPrint some contents")
print(config.get('other', 'use_anonymous')) # Just get the value
print(config.getboolean('other', 'use_anonymous')) # You know the datatype?
哪个输出
List all contents
Section: mysql
x host:::localhost:::<type 'str'>
x user:::root:::<type 'str'>
x passwd:::my secret password:::<type 'str'>
x db:::write-math:::<type 'str'>
Section: other
x preprocessing_queue:::["preprocessing.scale_and_center",
"preprocessing.dot_reduction",
"preprocessing.connect_lines"]:::<type 'str'>
x use_anonymous:::yes:::<type 'str'>
Print some contents
yes
True
如您所见,您可以使用易于读写的标准数据格式。 getboolean 和 getint 等方法允许您获取数据类型而不是简单的字符串。
编写配置
import os
configfile_name = "config.yaml"
# Check if there is already a configurtion file
if not os.path.isfile(configfile_name):
# Create the configuration file as it doesn't exist yet
cfgfile = open(configfile_name, 'w')
# Add content to the file
Config = ConfigParser.ConfigParser()
Config.add_section('mysql')
Config.set('mysql', 'host', 'localhost')
Config.set('mysql', 'user', 'root')
Config.set('mysql', 'passwd', 'my secret password')
Config.set('mysql', 'db', 'write-math')
Config.add_section('other')
Config.set('other',
'preprocessing_queue',
['preprocessing.scale_and_center',
'preprocessing.dot_reduction',
'preprocessing.connect_lines'])
Config.set('other', 'use_anonymous', True)
Config.write(cfgfile)
cfgfile.close()
结果
[mysql]
host = localhost
user = root
passwd = my secret password
db = write-math
[other]
preprocessing_queue = ['preprocessing.scale_and_center', 'preprocessing.dot_reduction', 'preprocessing.connect_lines']
use_anonymous = True
XML 基本示例
似乎根本不被 Python 社区用于配置文件。但是,解析/编写 XML 很容易,并且使用 Python 有很多可能性。一个是 BeautifulSoup:
from BeautifulSoup import BeautifulSoup
with open("config.xml") as f:
content = f.read()
y = BeautifulSoup(content)
print(y.mysql.host.contents[0])
for tag in y.other.preprocessing_queue:
print(tag)
config.xml 可能看起来像这样
<config>
<mysql>
<host>localhost</host>
<user>root</user>
<passwd>my secret password</passwd>
<db>write-math</db>
</mysql>
<other>
<preprocessing_queue>
<li>preprocessing.scale_and_center</li>
<li>preprocessing.dot_reduction</li>
<li>preprocessing.connect_lines</li>
</preprocessing_queue>
<use_anonymous value="true" />
</other>
</config>
【讨论】:
不错的代码/示例。小评论——您的 YAML 示例未使用 YAML,而是使用 INI 样式格式。 需要注意的是,至少python 2版本的ConfigParser会在读取时静默地将存储的列表转换为字符串。 IE。 CP.set('section','option',[1,2,3]) 保存和读取配置后将是 CP.get('section','option') => '1, 2, 3'跨度> 【参考方案5】:尝试使用ReadSettings:
from readsettings import ReadSettings
data = ReadSettings("settings.json") # Load or create any json, yml, yaml or toml file
data["name"] = "value" # Set "name" to "value"
data["name"] # Returns: "value"
【讨论】:
【参考方案6】:尝试使用cfg4py:
-
分层设计,支持多种环境,因此切勿将开发设置与生产站点设置混为一谈。
代码完成。 Cfg4py 会将您的 yaml 转换为 python 类,然后在您输入代码时可以使用代码完成。
还有更多..
免责声明:我是这个模块的作者
【讨论】:
【参考方案7】:对于简单的配置文件,我更喜欢 JSON 文件,例如conf.json:
"version": 1,
"bind":
"address": "127.0.0.1",
"port": 8080
,
"data":
"a": [1, 2, 3],
"b": 2.5
然后创建这个自定义 JSON 配置阅读器:
import json
class Dict(dict):
"""dot.notation access to dictionary attributes"""
__getattr__ = dict.get
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
class Configuration(object):
@staticmethod
def __load__(data):
if type(data) is dict:
return Configuration.load_dict(data)
else:
return data
@staticmethod
def load_dict(data: dict):
result = Dict()
for key, value in data.items():
result[key] = Configuration.__load__(value)
return result
@staticmethod
def load_json(path: str):
with open(path, "r") as f:
result = Configuration.__load__(json.loads(f.read()))
return result
最后,使用命令加载它:
confjson = Configuration.load_json('conf.json')
现在您可以使用点“。”访问您的配置。例如:
print(conf.version)
print(conf.bind.address)
print(conf.bind.port)
print(conf.data.a)
print(conf.data.b)
【讨论】:
以上是关于Python:你将如何保存一个简单的设置/配置文件?的主要内容,如果未能解决你的问题,请参考以下文章