17

ConfigParserを使用して、同じキーの複数の値を読み取ることができる必要があります。構成ファイルの例:

[test]
foo = value1
foo = value2
xxx = yyy

の「標準的な」使用では、値を持つConfigParser1 つのキーがあります。しかし、両方の値を読み取るパーサーが必要です。foovalue2

重複キーのエントリに続いて、次のサンプル コードを作成しました。

from collections import OrderedDict
from ConfigParser import RawConfigParser

class OrderedMultisetDict(OrderedDict):
    def __setitem__(self, key, value):

        try:
            item = self.__getitem__(key)
        except KeyError:
            super(OrderedMultisetDict, self).__setitem__(key, value)
            return

        print "item: ", item, value
        if isinstance(value, list):
            item.extend(value)
        else:
            item.append(value)
        super(OrderedMultisetDict, self).__setitem__(key, item)


config = RawConfigParser(dict_type = OrderedDict)
config.read(["test.cfg"])
print config.get("test",  "foo")
print config.get("test",  "xxx")

config2 = RawConfigParser(dict_type = OrderedMultisetDict)
config2.read(["test.cfg"])
print config2.get("test",  "foo")
print config.get("test",  "xxx")

最初の部分 ( with config) は、「通常」の構成ファイルを読み取り、(他の値の上書き/削除) のvalue2値のみを残して、次の期待される出力を取得します。foo

value2
yyy

2 番目の部分 ( config2) は私のアプローチを使用して複数の値をリストに追加しますが、出力は代わりに

['value1', 'value2', 'value1\nvalue2']
['yyy', 'yyy']

繰り返し値を取り除くにはどうすればよいですか? 次のような出力が期待されます。

['value1', 'value2']
yyy

また

['value1', 'value2']
['yyy']

(すべての値がリストにあるかどうかは気にしません...)。どんな提案でも大歓迎です。

4

5 に答える 5

17

少し変更した後、私はあなたが望むものを達成することができました:

class MultiOrderedDict(OrderedDict):
    def __setitem__(self, key, value):
        if isinstance(value, list) and key in self:
            self[key].extend(value)
        else:
            super(MultiOrderedDict, self).__setitem__(key, value)
            # super().__setitem__(key, value) in Python 3

config = ConfigParser.RawConfigParser(dict_type=MultiOrderedDict)
config.read(['a.txt'])
print config.get("test",  "foo")
print config.get("test",  "xxx")

出力:

['value1', 'value2']
['yyy']
于 2013-04-06T08:57:48.073 に答える
-1

その他の例 の複数の値test.cfg

[test]
foo = value1
foo = value2
 value3
xxx = yyy

<whitespace>value3value3foo リストに追加します。

ConfigParserリストを文字列に変換します。

/usr/lib/python2.7/ConfigParser.pyc in _read(self, fp, fpname)
    552             for name, val in options.items():
    553                 if isinstance(val, list):
--> 554                     options[name] = '\n'.join(val)
    555 

value変換前は常に list または dict ( MultiOrderedDict) です。

これを試してみてください-それでconfig.itemsうまくいきます:

from collections import OrderedDict
import ConfigParser

class MultiOrderedDict(OrderedDict):
    def __setitem__(self, key, value):
        if key in self:
            if isinstance(value, list):
                self[key].extend(value)
                return
            elif isinstance(value,str):
                return # ignore conversion list to string (line 554)
        super(MultiOrderedDict, self).__setitem__(key, value)

config = ConfigParser.RawConfigParser(dict_type=MultiOrderedDict)
config.read(['test.cfg'])
print config.get("test",  "foo")
print config.get("test",  "xxx")
print config.items("test")

出力:

['value1', 'value2', 'value3']
['yyy']
[('foo', ['value1', 'value2', 'value3']), ('xxx', ['yyy'])]

別の実装MultiOrderedDict

class MultiOrderedDict(OrderedDict):
    def __setitem__(self, key, value):
        if key in self:
            if isinstance(value, list):
                self[key].extend(value)
                return
            elif isinstance(value,str):
                if len(self[key])>1:
                    return
        super(MultiOrderedDict, self).__setitem__(key, value)

出力:

['value1', 'value2', 'value3']
yyy
[('foo', ['value1', 'value2', 'value3']), ('xxx', 'yyy')]
于 2016-07-09T21:35:37.143 に答える