문제

일반적인 configparser 생성 파일은 다음과 같습니다.

[Section]
bar=foo
[Section 2]
bar2= baz

이제 예를 들어 다음과 같은 목록을 색인하는 방법이 있습니까?

[Section 3]
barList={
    item1,
    item2
}

관련 질문 : 섹션 당 Python의 ConfigParser 고유 키

도움이 되었습니까?

해결책

목록을 구분 된 문자열로 포장하지 못하게 한 다음 구성에서 문자열을 가져 오면 포장을 풀지 않습니다. 이렇게하면 구성 섹션이 다음과 같습니다.

[Section 3]
barList=item1,item2

예쁘지는 않지만 대부분의 간단한 목록에서는 기능적입니다.

다른 팁

또한 조금 늦었지만 일부는 도움이 될 수 있습니다. ConfigParser와 JSON의 조합을 사용하고 있습니다.

[Foo]
fibs: [1,1,2,3,5,8,13]

다음과 같이 읽으십시오.

>>> json.loads(config.get("Foo","fibs"))
[1, 1, 2, 3, 5, 8, 13]

목록이 길면 라인을 깨뜨릴 수도 있습니다 ( @Peter-Smit 감사합니다) :

[Bar]
files_to_check = [
     "/path/to/file1",
     "/path/to/file2",
     "/path/to/another file with space in the name"
     ]

물론 JSON 만 사용할 수는 있지만 구성 파일이 훨씬 더 읽기 쉬우 며 [기본] 섹션은 매우 편리합니다.

이 파티에 늦게 왔지만 최근에 목록에 대한 구성 파일의 전용 섹션으로 이것을 구현했습니다.

[paths]
path1           = /some/path/
path2           = /another/path/
...

그리고 사용 config.items( "paths" ) 반복 가능한 경로 항목 목록을 얻으려면 :

path_items = config.items( "paths" )
for key, path in path_items:
    #do something with path

이것이 다른 사람들 이이 질문을 검색하는 데 도움이되기를 바랍니다.)

많은 사람들이 모르는 한 가지는 멀티 라인 구성 값이 허용된다는 것입니다. 예를 들어:

;test.ini
[hello]
barlist = 
    item1
    item2

의 가치 config.get('hello','barlist') 이제 : 이제 :

"\nitem1\nitem2"

Splitlines 메소드로 쉽게 분할 할 수 있습니다 (빈 항목을 필터링하는 것을 잊지 마십시오).

우리가 피라미드와 같은 큰 프레임 워크를 보면 그들은이 기술을 사용하고 있습니다.

def aslist_cronly(value):
    if isinstance(value, string_types):
        value = filter(None, [x.strip() for x in value.splitlines()])
    return list(value)

def aslist(value, flatten=True):
    """ Return a list of strings, separating the input based on newlines
    and, if flatten=True (the default), also split on spaces within
    each line."""
    values = aslist_cronly(value)
    if not flatten:
        return values
    result = []
    for value in values:
        subvalues = value.split()
        result.extend(subvalues)
    return result

원천

나 자신, 이것이 당신에게 흔한 일이라면 configparser를 확장 할 것입니다.

class MyConfigParser(ConfigParser):
    def getlist(self,section,option):
        value = self.get(section,option)
        return list(filter(None, (x.strip() for x in value.splitlines())))

    def getlistint(self,section,option):
        return [int(x) for x in self.getlist(section,option)]

이 기술을 사용할 때 찾아야 할 몇 가지 사항이 있습니다.

  1. 항목 인 새로운 라인은 공백으로 시작해야합니다 (예 : 공간 또는 탭)
  2. 공백으로 시작하는 모든 다음 줄은 이전 항목의 일부로 간주됩니다. 또한 = 부호가 있거나 a로 시작하는 경우; 공백에 따라.

당신이 원한다면 문자 그대로 목록을 통과 한 다음 사용할 수 있습니다.

ast.literal_eval()

예를 들어 구성 :

[section]
option=["item1","item2","item3"]

코드는 다음과 같습니다.

import ConfigParser
import ast

my_list = ast.literal_eval(config.get("section", "option"))
print(type(my_list))
print(my_list)

산출:

<type'list'>
["item1","item2","item3"]

나는 이것을 소비하려고 여기에 착륙했다 ...

[global]
spys = richard.sorge@cccp.gov, mata.hari@deutschland.gov

대답은 쉼표로 나누고 공간을 벗기는 것입니다.

SPYS = [e.strip() for e in parser.get('global', 'spys').split(',')]

목록 결과를 얻으려면 :

['richard.sorge@cccp.gov', 'mata.hari@deutschland.gov']

그것은 OP의 질문에 정확히 대답하지는 않지만 일부 사람들이 찾고있는 간단한 대답 일 수 있습니다.

언급이 없습니다 converters Kwarg에 대한 ConfigParser() 이 답변 중 어느 것도 다소 실망 스러웠습니다.

문서에 따르면 사전을 전달할 수 있습니다. ConfigParser 추가 할 것입니다 get 파서와 섹션 프록시 모두에 대한 방법. 목록을 위해 :

example.ini

[Germ]
germs: a,list,of,names, and,1,2, 3,numbers

Parser 예 :

cp = ConfigParser(converters={'list': lambda x: [i.strip() for i in x.split(',')]})
cp.read('example.ini')
cp.getlist('Germ', 'germs')
['a', 'list', 'of', 'names', 'and', '1', '2', '3', 'numbers']
cp['Germ'].getlist('germs')
['a', 'list', 'of', 'names', 'and', '1', '2', '3', 'numbers']

서브 클래싱이 필요하지 않기 때문에 이것은 개인적으로 가장 좋아하는 것입니다. JSON 또는 해석 할 수있는 목록을 완벽하게 작성하기 위해 최종 사용자에게 의존 할 필요가 없습니다. ast.literal_eval.

이것이 내가 목록에 사용하는 것입니다.

파일 컨텐츠 구성 :

[sect]
alist = a
        b
        c

코드 :

l = config.get('sect', 'alist').split('\n')

그것은 줄에 작동합니다

숫자의 경우

구성 컨텐츠 :

nlist = 1
        2
        3

암호:

nl = config.get('sect', 'alist').split('\n')
l = [int(nl) for x in nl]

감사해요.

Config Parser에 의해 직렬화를 위해 원시 유형 만 지원됩니다. 그런 종류의 요구 사항에 대해 JSON 또는 YAML을 사용합니다.

나는 과거에도 같은 문제에 직면했다. 더 복잡한 목록이 필요한 경우 configparser에서 상속하여 자신의 파서를 만드는 것을 고려하십시오. 그런 다음 GET 메소드를 덮어 씁니다.

    def get(self, section, option):
    """ Get a parameter
    if the returning value is a list, convert string value to a python list"""
    value = SafeConfigParser.get(self, section, option)
    if (value[0] == "[") and (value[-1] == "]"):
        return eval(value)
    else:
        return value

이 솔루션을 사용하면 구성 파일에서 사전을 정의 할 수도 있습니다.

그러나 조심하세요! 이것은 안전하지 않습니다. 이는 누구나 구성 파일을 통해 코드를 실행할 수 있음을 의미합니다. 프로젝트에서 보안이 문제가되지 않으면 직접 Python 클래스를 구성 파일로 사용하는 것이 좋습니다. 다음은 configparser 파일보다 훨씬 강력하고 소모품입니다.

class Section
    bar = foo
class Section2
    bar2 = baz
class Section3
    barList=[ item1, item2 ]
import ConfigParser
import os

class Parser(object):
    """attributes may need additional manipulation"""
    def __init__(self, section):
        """section to retun all options on, formatted as an object
        transforms all comma-delimited options to lists
        comma-delimited lists with colons are transformed to dicts
        dicts will have values expressed as lists, no matter the length
        """
        c = ConfigParser.RawConfigParser()
        c.read(os.path.join(os.path.dirname(__file__), 'config.cfg'))

        self.section_name = section

        self.__dict__.update({k:v for k, v in c.items(section)})

        #transform all ',' into lists, all ':' into dicts
        for key, value in self.__dict__.items():
            if value.find(':') > 0:
                #dict
                vals = value.split(',')
                dicts = [{k:v} for k, v in [d.split(':') for d in vals]]
                merged = {}
                for d in dicts:
                    for k, v in d.items():
                        merged.setdefault(k, []).append(v)
                self.__dict__[key] = merged
            elif value.find(',') > 0:
                #list
                self.__dict__[key] = value.split(',')

그래서 이제 내 config.cfg 파일은 다음과 같이 보일 수 있습니다.

[server]
credentials=username:admin,password:$3<r3t
loggingdirs=/tmp/logs,~/logs,/var/lib/www/logs
timeoutwait=15

내 작은 프로젝트를 위해 세밀한 객체로 구문 분석 할 수 있습니다.

>>> import config
>>> my_server = config.Parser('server')
>>> my_server.credentials
{'username': ['admin'], 'password', ['$3<r3t']}
>>> my_server.loggingdirs:
['/tmp/logs', '~/logs', '/var/lib/www/logs']
>>> my_server.timeoutwait
'15'

이것은 간단한 구성의 매우 빠른 구문 분석을위한 것입니다. ints, bols 및 기타 유형의 출력을 가져 오는 모든 능력을 잃어 버립니다. Parser, 또는 다른 곳에서 파서 클래스가 달성 한 구문 분석 작업을 다시 수행합니다.

json.loads & ast.literal_eval 구성 내에서 간단한 목록은 각 문자를 바이트로 취급하므로 사각형 브래킷을 반환하는 것입니다 ....

구성이있는 경우 의미 fieldvalue = [1,2,3,4,5]

그 다음에 config.read(*.cfg) config['fieldValue'][0] 반환 [ 대신에 1

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top