当前位置:  开发笔记 > 编程语言 > 正文

在Python中解析.properties文件

如何解决《在Python中解析.properties文件》经验,为你挑选了6个好方法。

ConfigParser如果解析一个简单的Java风格的.properties 文件,该模块会引发异常,该文件的内容是键值对(i..e没有INI样式的节头).有一些解决方法吗?



1> Alex Martell..:

说你有,例如:

$ cat my.props
first: primo
second: secondo
third: terzo

ie将是一种.config格式,除了它缺少一个前导部分名称.然后,很容易伪造节标题:

import ConfigParser

class FakeSecHead(object):
    def __init__(self, fp):
        self.fp = fp
        self.sechead = '[asection]\n'

    def readline(self):
        if self.sechead:
            try: 
                return self.sechead
            finally: 
                self.sechead = None
        else: 
            return self.fp.readline()

用法:

cp = ConfigParser.SafeConfigParser()
cp.readfp(FakeSecHead(open('my.props')))
print cp.items('asection')

输出:

[('second', 'secondo'), ('third', 'terzo'), ('first', 'primo')]


如果在`configparser`中有一个选项可以抑制该异常,为了像我这样的凡人:)会很棒

2> 小智..:

我认为MestreLion的"read_string"评论很简单,值得一个例子.

对于Python 3.2+,您可以像这样实现"虚拟部分"的想法:

with open(CONFIG_PATH, 'r') as f:
    config_string = '[dummy_section]\n' + f.read()
config = configparser.ConfigParser()
config.read_string(config_string)



3> tauran..:

我的解决方案是使用StringIO并添加一个简单的虚拟标头:

import StringIO
import os
config = StringIO.StringIO()
config.write('[dummysection]\n')
config.write(open('myrealconfig.ini').read())
config.seek(0, os.SEEK_SET)

import ConfigParser
cp = ConfigParser.ConfigParser()
cp.readfp(config)
somevalue = cp.getint('dummysection', 'somevalue')



4> 小智..:

Alex Martelli的上述答案对Python 3.2+不起作用:readfp()已被替换为read_file(),现在它需要一个迭代器而不是使用该readline()方法.

这是一个使用相同方法的片段,但适用于Python 3.2+.

>>> import configparser
>>> def add_section_header(properties_file, header_name):
...   # configparser.ConfigParser requires at least one section header in a properties file.
...   # Our properties file doesn't have one, so add a header to it on the fly.
...   yield '[{}]\n'.format(header_name)
...   for line in properties_file:
...     yield line
...
>>> file = open('my.props', encoding="utf_8")
>>> config = configparser.ConfigParser()
>>> config.read_file(add_section_header(file, 'asection'), source='my.props')
>>> config['asection']['first']
'primo'
>>> dict(config['asection'])
{'second': 'secondo', 'third': 'terzo', 'first': 'primo'}
>>>


`add_section_header`可以简单地是:`config.read_file(itertools.chain(['[SECTION_NAME]'],file))`
Python 3.2还添加了`read_string()`,这使得虚拟部分附加一个简单的任务.

5> Jossef Harus..:

好极了!另一个版本

根据此答案(添加的内容使用dictwith语句和支持%字符)

import ConfigParser
import StringIO
import os

def read_properties_file(file_path):
    with open(file_path) as f:
        config = StringIO.StringIO()
        config.write('[dummy_section]\n')
        config.write(f.read().replace('%', '%%'))
        config.seek(0, os.SEEK_SET)

        cp = ConfigParser.SafeConfigParser()
        cp.readfp(config)

        return dict(cp.items('dummy_section'))

用法

props = read_properties_file('/tmp/database.properties')

# It will raise if `name` is not in the properties file
name = props['name']

# And if you deal with optional settings, use:
connection_string = props.get('connection-string')
password = props.get('password')

print name, connection_string, password

.properties我的示例中使用的文件

name=mongo
connection-string=mongodb://...
password=my-password%1234

编辑2015-11-06

感谢Neill Lima提到%角色存在问题。

这样做的原因是ConfigParser为了分析.ini文件。该%字符是一个特殊的语法。为了使用%简单相加AA字符替换为%%%根据.ini语法。



6> 小智..:
with open('some.properties') as file:
    props = dict(line.strip().split('=', 1) for line in file)

归功于如何从文本文件中创建包含键值对的字典

maxsplit=1如果值中有等号,则很重要(例如someUrl=https://some.site.com/endpoint?id=some-value&someotherkey=value


如果文件有注释,这将出错。我们可以这样避免:`dict(line.strip()。split('=',1)如果不是line.startswith(“#”)而不是len(line.strip())==,则表示文件中的行0)`
推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有