51

モジュールは 、コンテンツがキーと値のペアである(つまり、INIスタイルのセクションヘッダーがない)ConfigParser単純なJavaスタイルのファイルを解析する場合に例外を発生させます。.propertiesいくつかの回避策はありますか?

4

10 に答える 10

79

たとえば、次のようにします。

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

つまり.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')]
于 2010-05-12T14:36:38.823 に答える
32

私の解決策は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')
于 2011-12-28T15:13:32.043 に答える
21

上記の 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'}
>>>
于 2011-12-18T23:46:01.637 に答える
6

わーい!別のバージョン

この回答に基づいて(追加は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

キャラクターに問題があったと言及したニール・リマに感謝し%ます。

その理由は、ファイルConfigParserを解析するように設計されてい.iniます。文字は%特殊な構文です。単純に追加された文字を使用するには、構文に従って%aa を%withに置き換えます。%%.ini

于 2015-02-17T13:54:41.837 に答える
2

この回答は、Python 3 で itertools.chain を使用することを提案しています。

from configparser import ConfigParser
from itertools import chain

parser = ConfigParser()
with open("foo.conf") as lines:
    lines = chain(("[dummysection]",), lines)  # This line does the trick.
    parser.read_file(lines)
于 2016-08-17T21:56:14.310 に答える
-1
with open('mykeyvaluepairs.properties') as f:
    defaults = dict([line.split() for line in f])
config = configparser.ConfigParser(defaults)
config.add_section('dummy_section')

config.get('dummy_section', option)DEFAULT セクションから 'option' を返すようになりました。

また:

with open('mykeyvaluepairs.properties') as f:
    properties = dict([line.split() for line in f])
config = configparser.ConfigParser()
config.add_section('properties')
for prop, val in properties.items():
    config.set('properties', prop, val)

その場合config.get('properties', option)、デフォルトのセクションに頼りません。

于 2013-09-08T05:43:29.213 に答える