ConfigParser를 사용하여 섹션 이름없이 파일 읽기
ConfigParser
스크립트의 런타임 구성을 읽는 데 사용 하고 있습니다.
섹션 이름을 제공하지 않는 유연성을 갖고 싶습니다 (충분히 간단한 스크립트가 있으며 '섹션'이 필요하지 않음). 예외 ConfigParser
가 NoSectionError
발생하고 파일을 수락하지 않습니다.
ConfigParser가 (key, value)
섹션 이름없이 구성 파일 의 튜플을 검색하도록하려면 어떻게해야합니까?
예를 들면 :
key1=val1
key2:val2
차라리 구성 파일에 쓰지 않습니다.
Alex Martelli 는 파일 (분명히 섹션없는 구성 파일) ConfigParser
을 구문 분석 하는 데 사용 하는 솔루션 을 제공했습니다.properties
.
그의 솔루션 은 ConfigParser
의 요구 사항 을 충족하기 위해 더미 섹션 제목을 자동으로 삽입하는 파일과 같은 래퍼입니다 .
jterrace 의이 답변에 의해 깨달음에 따라 다음 과 같은 해결책 을 찾았 습니다.
- 전체 파일을 문자열로 읽기
- 기본 섹션 이름이있는 접두사
- StringIO를 사용하여 파일 류 객체 모방
ini_str = '[root]\n' + open(ini_path, 'r').read()
ini_fp = StringIO.StringIO(ini_str)
config = ConfigParser.RawConfigParser()
config.readfp(ini_fp)
향후 Google 사용자를위한 수정 : Python 3.4 readfp
이상에서는 StringIO
더 이상 사용되지 않으며 더 이상 필요하지 않습니다. 대신 다음을 read_string
직접 사용할 수 있습니다.
with open('config_file') as f:
file_content = '[dummy_section]\n' + f.read()
config_parser = ConfigParser.RawConfigParser()
config_parser.read_string(file_content)
한 줄의 코드로이 작업을 수행 할 수 있습니다.
Python 3에서는 구성 파일 데이터에 가짜 섹션 헤더를 추가하고 read_string()
.
from configparser import ConfigParser
parser = ConfigParser()
with open("foo.conf") as stream:
parser.read_string("[top]\n" + stream.read()) # This line does the trick.
에 itertools.chain()
대한 섹션 헤더를 시뮬레이션하는 데 사용할 수도 있습니다 read_file()
. 이는 위의 접근 방식보다 메모리 효율성이 더 높을 수 있으며, 제한된 런타임 환경에 큰 구성 파일이있는 경우 유용 할 수 있습니다.
from configparser import ConfigParser
from itertools import chain
parser = ConfigParser()
with open("foo.conf") as lines:
lines = chain(("[top]",), lines) # This line does the trick.
parser.read_file(lines)
Python 2에서는 구성 파일 데이터에 가짜 섹션 헤더를 추가하고 결과를 StringIO
객체 에 래핑 한 다음 readfp()
.
from ConfigParser import ConfigParser
from StringIO import StringIO
parser = ConfigParser()
with open("foo.conf") as stream:
stream = StringIO("[top]\n" + stream.read()) # This line does the trick.
parser.readfp(stream)
이러한 접근 방식을 사용하면에서 구성 설정을 사용할 수 있습니다 parser.items('top')
.
이전 및 새 Python 인터프리터와의 호환성을 위해 Python 3에서도 StringIO를 사용할 수 있지만 이제는 io
패키지에 있으며 readfp()
이제 더 이상 사용되지 않습니다.
또는 ConfigParser 대신 TOML 파서를 사용하는 것을 고려할 수 있습니다 .
ConfigObj 라이브러리를 사용하여 간단히 수행 할 수 있습니다. http://www.voidspace.org.uk/python/configobj.html
Debian / Ubuntu를 사용하는 경우 패키지 관리자를 사용하여이 모듈을 설치할 수 있습니다.
apt-get install python-configobj
사용 예 :
from configobj import ConfigObj
config = ConfigObj('myConfigFile.ini')
config.get('key1') # You will get val1
config.get('key2') # You will get val2
이 작업을 수행하는 가장 쉬운 방법은 제 생각에 파이썬의 CSV 파서를 사용하는 것입니다. 다음은이 접근 방식과 테스트 드라이버를 보여주는 읽기 / 쓰기 기능입니다. 값이 여러 줄로 허용되지 않는 경우 작동합니다. :)
import csv
import operator
def read_properties(filename):
""" Reads a given properties file with each line of the format key=value. Returns a dictionary containing the pairs.
Keyword arguments:
filename -- the name of the file to be read
"""
result={ }
with open(filename, "rb") as csvfile:
reader = csv.reader(csvfile, delimiter='=', escapechar='\\', quoting=csv.QUOTE_NONE)
for row in reader:
if len(row) != 2:
raise csv.Error("Too many fields on row with contents: "+str(row))
result[row[0]] = row[1]
return result
def write_properties(filename,dictionary):
""" Writes the provided dictionary in key-sorted order to a properties file with each line of the format key=value
Keyword arguments:
filename -- the name of the file to be written
dictionary -- a dictionary containing the key/value pairs.
"""
with open(filename, "wb") as csvfile:
writer = csv.writer(csvfile, delimiter='=', escapechar='\\', quoting=csv.QUOTE_NONE)
for key, value in sorted(dictionary.items(), key=operator.itemgetter(0)):
writer.writerow([ key, value])
def main():
data={
"Hello": "5+5=10",
"World": "Snausage",
"Awesome": "Possum"
}
filename="test.properties"
write_properties(filename,data)
newdata=read_properties(filename)
print "Read in: "
print newdata
print
contents=""
with open(filename, 'rb') as propfile:
contents=propfile.read()
print "File contents:"
print contents
print ["Failure!", "Success!"][data == newdata]
return
if __name__ == '__main__':
main()
이 문제를 직접 겪은 후, 수락 된 답변에 연결된 Alex Martelli의 접근 방식을 기반으로 섹션없이 투명하게 파일을 읽고 쓸 수있는 ConfigParser (Python 2 버전)에 완전한 래퍼를 작성했습니다. ConfigParser 사용에 대한 드롭 인 교체 여야합니다. 필요한 사람이이 페이지를 찾을 수 있도록 게시합니다.
import ConfigParser
import StringIO
class SectionlessConfigParser(ConfigParser.RawConfigParser):
"""
Extends ConfigParser to allow files without sections.
This is done by wrapping read files and prepending them with a placeholder
section, which defaults to '__config__'
"""
def __init__(self, *args, **kwargs):
default_section = kwargs.pop('default_section', None)
ConfigParser.RawConfigParser.__init__(self, *args, **kwargs)
self._default_section = None
self.set_default_section(default_section or '__config__')
def get_default_section(self):
return self._default_section
def set_default_section(self, section):
self.add_section(section)
# move all values from the previous default section to the new one
try:
default_section_items = self.items(self._default_section)
self.remove_section(self._default_section)
except ConfigParser.NoSectionError:
pass
else:
for (key, value) in default_section_items:
self.set(section, key, value)
self._default_section = section
def read(self, filenames):
if isinstance(filenames, basestring):
filenames = [filenames]
read_ok = []
for filename in filenames:
try:
with open(filename) as fp:
self.readfp(fp)
except IOError:
continue
else:
read_ok.append(filename)
return read_ok
def readfp(self, fp, *args, **kwargs):
stream = StringIO()
try:
stream.name = fp.name
except AttributeError:
pass
stream.write('[' + self._default_section + ']\n')
stream.write(fp.read())
stream.seek(0, 0)
return ConfigParser.RawConfigParser.readfp(self, stream, *args,
**kwargs)
def write(self, fp):
# Write the items from the default section manually and then remove them
# from the data. They'll be re-added later.
try:
default_section_items = self.items(self._default_section)
self.remove_section(self._default_section)
for (key, value) in default_section_items:
fp.write("{0} = {1}\n".format(key, value))
fp.write("\n")
except ConfigParser.NoSectionError:
pass
ConfigParser.RawConfigParser.write(self, fp)
self.add_section(self._default_section)
for (key, value) in default_section_items:
self.set(self._default_section, key, value)
Blueicefield의 답변은 configobj를 언급했지만 원래 lib는 Python 2 만 지원합니다. 이제 Python 3+ 호환 포트가 있습니다.
https://github.com/DiffSK/configobj
API는 변경되지 않았습니다 . doc 참조하십시오 .
참고 URL : https://stackoverflow.com/questions/2885190/using-configparser-to-read-a-file-without-section-name
'Programing' 카테고리의 다른 글
GoogleSignIn, AdMob으로 인해 '앱이 사용 설명없이 개인 정보에 민감한 데이터에 액세스하려고 시도'앱 제출시 iOS 10 GM 출시 오류 (0) | 2020.10.10 |
---|---|
복합 키 사전 (0) | 2020.10.10 |
여러 GZip 파일의 빠른 연결 (0) | 2020.10.10 |
문자열에서 문자의 위치 찾기 (0) | 2020.10.10 |
nop opcode의 목적은 무엇입니까? (0) | 2020.10.10 |