8

私は設定ファイルを持っています、

[local]
    variable1 : val1 ;#comment1
    variable2 : val2 ;#comment2

次のようなコードは、キーの値のみを読み取ります。

class Config(object):
    def __init__(self):
        self.config = ConfigParser.ConfigParser()
        self.config.read('config.py')

    def get_path(self):
        return self.config.get('local', 'variable1')

if __name__ == '__main__':
    c = Config()
    print c.get_path()

しかし、値とともに存在するコメントも読みたいと思います。この点に関する提案は非常に役立ちます。

4

5 に答える 5

8

残念ながら、これは一般的なケースでは簡単に実行できません。コメントは、パーサーによって無視されるはずです。

#特定のケースでは、行の先頭にある場合にのみコメント文字として機能するため、簡単です。したがって、 variable1 の値は になります"val1 #comment1"。私はあなたがこのようなものを使っていると思いますが、壊れにくいだけです:

val1_line = c.get('local', 'var1')
val1, comment = val1_line.split(' #') 

「コメント」の値が必要な場合、おそらくそれは適切なコメントではありませんか? 次のように、「コメント」に明示的なキーを追加することを検討してください。

[local]
  var1: 108.5j
  var1_comment: remember, the flux capacitor capacitance is imaginary! 
于 2012-02-02T10:16:05.213 に答える
2

ConfigParserモジュールのドキュメントによると、

構成ファイルには、特定の文字 (# および ;) を先頭に付けたコメントを含めることができます。コメントは、空の行に単独で表示されるか、値またはセクション名を含む行に入力されます。後者の場合、コメントとして認識されるように、先頭に空白文字を付ける必要があります。(下位互換性のため、インライン コメントを開始するのは ; のみで、# は開始しません。)

値とともに「コメント」を読みたい場合は、文字の前の空白を省略する;か、#. ただし、この場合、文字列comment1comment2は値の一部になり、コメントとは見なされなくなります。

より良いアプローチは、 などの別のプロパティ名を使用するvariable1_commentか、コメント専用の構成で別のセクションを定義することです。

[local]
    variable1 = value1
[comments]
    variable1 = comment1

最初の解決策では、別のキーを使用して新しいキーを生成する必要があります (つまり、 から計算variable1_commentするvariable1)。もう 1 つの解決策では、構成ファイル内の異なるセクションを対象とする同じキーを使用できます。

Python 2.7.2 の時点で、文字を使用する場合、行に沿ってコメントを読むことが常に可能です。#ドキュメントが言うように、それは下位互換性のためです。次のコードはスムーズに実行されるはずです。

config = ConfigParser.ConfigParser()
config.read('config.ini')
assert config.get('local', 'variable1') == 'value1'
assert config.get('local', 'variable2') == 'value2 # comment2'

次のconfig.iniファイルの場合:

[local]
variable1 = value1 ; comment1
variable2 = value2 # comment2

この解決策を採用する場合はget()、値とコメントの結果を手動で解析することを忘れないでください。

于 2012-02-02T10:24:05.287 に答える
2

あなたの唯一の解決策はConfigParser、メソッドをオーバーライドする別のものを書くこと_read()です。ConfigParserコメントの削除に関するすべてのチェックを削除する必要があります。これは危険な解決策ですが、うまくいくはずです。

class ValuesWithCommentsConfigParser(ConfigParser.ConfigParser):

    def _read(self, fp, fpname):
        from ConfigParser import DEFAULTSECT, MissingSectionHeaderError, ParsingError

        cursect = None                        # None, or a dictionary
        optname = None
        lineno = 0
        e = None                              # None, or an exception
        while True:
            line = fp.readline()
            if not line:
                break
            lineno = lineno + 1
            # comment or blank line?
            if line.strip() == '' or line[0] in '#;':
                continue
            if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
                # no leading whitespace
                continue
                # continuation line?
            if line[0].isspace() and cursect is not None and optname:
                value = line.strip()
                if value:
                    cursect[optname].append(value)
            # a section header or option header?
            else:
                # is it a section header?
                mo = self.SECTCRE.match(line)
                if mo:
                    sectname = mo.group('header')
                    if sectname in self._sections:
                        cursect = self._sections[sectname]
                    elif sectname == DEFAULTSECT:
                        cursect = self._defaults
                    else:
                        cursect = self._dict()
                        cursect['__name__'] = sectname
                        self._sections[sectname] = cursect
                        # So sections can't start with a continuation line
                    optname = None
                # no section header in the file?
                elif cursect is None:
                    raise MissingSectionHeaderError(fpname, lineno, line)
                # an option line?
                else:
                    mo = self._optcre.match(line)
                    if mo:
                        optname, vi, optval = mo.group('option', 'vi', 'value')
                        optname = self.optionxform(optname.rstrip())
                        # This check is fine because the OPTCRE cannot
                        # match if it would set optval to None
                        if optval is not None:
                            optval = optval.strip()
                            # allow empty values
                            if optval == '""':
                                optval = ''
                            cursect[optname] = [optval]
                        else:
                            # valueless option handling
                            cursect[optname] = optval
                    else:
                        # a non-fatal parsing error occurred.  set up the
                        # exception but keep going. the exception will be
                        # raised at the end of the file and will contain a
                        # list of all bogus lines
                        if not e:
                            e = ParsingError(fpname)
                        e.append(lineno, repr(line))
            # if any parsing errors occurred, raise an exception
        if e:
            raise e

        # join the multi-line values collected while reading
        all_sections = [self._defaults]
        all_sections.extend(self._sections.values())
        for options in all_sections:
            for name, val in options.items():
                if isinstance(val, list):
                    options[name] = '\n'.join(val)

では、ValuesWithCommentsConfigParserいくつかのインポートを修正し、コードの適切なセクションを削除しました。

以前の回答と同じものを使用してconfig.ini、以前のコードが正しいことを証明できます。

config = ValuesWithCommentsConfigParser()
config.read('config.ini')
assert config.get('local', 'variable1') == 'value1 ; comment1'
assert config.get('local', 'variable2') == 'value2 # comment2'
于 2012-02-02T11:40:55.087 に答える
1

マニュアルによると: 「#」または「;」で始まる行 は無視され、コメントを提供するために使用される場合があります。

variable1 の値は「val1 #comment1」です。コメントは値の一部です。

コメントの前に Enter を入れるかどうか、設定を確認できます

于 2012-02-02T10:27:58.247 に答える