【发布时间】:2010-10-22 14:26:06
【问题描述】:
我有一个格式的文件
VarName=Value
.
.
我想将它读入一个散列,这样H("VarName") 将返回该值。
什么是快速的方法? (读取一组字符串,将它们全部拆分到等号所在的位置,然后放入哈希中?
我正在使用 python。
【问题讨论】:
标签: python configuration-files
我有一个格式的文件
VarName=Value
.
.
我想将它读入一个散列,这样H("VarName") 将返回该值。
什么是快速的方法? (读取一组字符串,将它们全部拆分到等号所在的位置,然后放入哈希中?
我正在使用 python。
【问题讨论】:
标签: python configuration-files
oneliner 答案:
H = dict(line.strip().split('=') for line in open('filename.txt'))
(如果值还可以包含“=”字符,则可以选择使用 .split() 和 maxsplit=1)
【讨论】:
也许ConfigParser可以帮到你。
【讨论】:
d = {}
with open('filename') as f:
for line in f:
key, value = line.split('=')
d[key] = value
编辑: 按照foret的建议,您可以将其更改为
for line in f:
tokens = line.split('=')
d[tokens[0]] = '='.join(tokens[1:])
这将处理值中允许使用等号的情况,但如果名称也可以包含等号,它仍然会失败——因为你需要一个真正的解析器。
【讨论】:
for line in f。
'x=y'="\"'z'=a\""这样的行,或者如果你不能引用部分文件格式是不明确的:x=y=z是指x -> y=z还是x=y -> z?
for that you would need a true parser 时指出,这意味着这不是在解析属性文件。如果您明确指出这不是解析 .properties 文件语法,我仍然更喜欢它,但这至少是一个开始。
接受@Steven 的回答并没有考虑属性文件中的 cmets 和换行符,这个可以:
H = dict(line.strip().split('=') for line in open('file.properties') if not line.startswith('#') and not line.startswith('\n'))
【讨论】:
【讨论】:
这可能是一个愚蠢的答案,但谁知道它可以帮助你:)
将文件的扩展名更改为 .py,并进行必要的更改,如下所示:
文件.py
VarName="Value" # if it's a string
VarName_2=1
# and you can also assign a dict a list to a var, how cool is that ?
并把它放在你的包树或sys.path中,现在你可以在脚本中这样调用它,当你想使用它时:
>>> import file
>>> file.VarName
'Value'
为什么我写这个答案是因为,这个文件到底是什么?我从来没有见过这样的conf文件,没有部分没有什么?为什么要创建这样的配置文件?它看起来像一个糟糕的配置文件,应该看起来像 Django 设置,我更喜欢尽可能使用类似于 django 设置的配置文件。
现在你可以把你的 -1 放在左边:)
【讨论】:
VarName:value 这样的行上中断,这两个字符都在: 字符上中断,而且你的value周围没有引号。
ConfigParser 是一个用于理解 .cfg 文件的库,因此如果您针对该库编写了一个不读取 .properties 的错误,他们很可能会将其踢回并拒绝它——无论如何我都会这样做。 .properties 文件不是 .cfg 解析器的责任。 .cfg 文件要求在大多数 .cfg 处理程序中存在一个部分,这就是引发该异常的原因。
csv module 可以让您轻松做到这一点:
import csv
H = dict([(row[0], row[1]) for row in csv.reader(open('the_file', 'r'), delimiter='=' )])
【讨论】:
对于 python2 有一个 jproperties https://pypi.python.org/pypi/jproperties/1.0.1
对于 python2/3 有 javaproperties http://javaproperties.readthedocs.io/en/v0.1.0/
就这么简单:
import os, javaproperties
with open(file, 'rb') as f:
properties_dict = javaproperties.load(f)
【讨论】:
好的,答案中没有其他人提到它,所以我想我会这样做。如果您正在编写 Python,并且可以控制您的解释器,也许您可以强制使用 Jython 解释器。
Jython 是一个完全用 Java 实现的 Python 解释器。所有的 Python 标准库都触手可及,还有所有可用的 Java SE 库的额外优势。
我实际上并没有执行以下任何操作(认为它更像是没有异常处理的伪代码),但是您可以混合和匹配 Python 和 Java 库,您的代码最终可能看起来像这样:
from java.util import Properties
from java.io import File, FileInputStream
import os
javasPropertyObject = Properties()
pathToPropFile = os.path.join('path', 'to', 'property', 'file.properties')
if os.path.isfile(pathToPropFile):
#this is java.io.File, not Python's file descriptor
propFile = File(pathToPropFile )
javasFileInputStreamObject = FileInputStream(propFile)
javasPropertyObject.load(javasFileInputStreamObject)
#now we can pull out Java properties as defined by the .property file grammar
myProp = javasPropertyObject.getProperty('myPropName')
这样的文件在哪里是有效的,而在简单的split on '=' 解决方案中却不是这样:
myPropName1:value
myPropName2=value
myPropName3=\
value
#this is a = comment
myPropName4:my \
value
myPropNameWithUnicode=\u0009
不利的一面是,您失去了在各种 Python 解释器之间移植的能力,现在您被锁定在 Jython 中。如果您也尝试这种方法,您将被锁定在图书馆中。我喜欢 Jython 的原因是你增加了所有可用的 Java SE 库的灵活性。
【讨论】:
如果您需要以简单的方式从属性文件中的某个部分读取所有值:
您的 config.properties 文件布局:
[SECTION_NAME]
key1 = value1
key2 = value2
你的代码:
import configparser
config = configparser.RawConfigParser()
config.read('path_to_config.properties file')
details_dict = dict(config.items('SECTION_NAME'))
这将为您提供一个字典,其中的键与配置文件中的键及其对应的值相同。
details_dict becomes
{'key1':'value1', 'key2':'value2'}
现在获取key1的值:
value_1 = details_dict['key1']
将所有内容放在一个方法中,该方法只从配置文件中读取该部分一次(在程序运行期间第一次调用该方法)。
def get_config_dict():
if not hasattr(get_config_dict, 'config_dict'):
get_config_dict.config_dict = dict(config.items('SECTION_NAME'))
return get_config_dict.config_dict
现在调用上述函数并获取所需键的值:
config_details = get_config_dict()
key_1_value = config_details['key1']
【讨论】: