configparser — 설정 파일 파서

configparser — 설정 파일 파서

(소스: Lib/configparser.py)

이 모듈은 마이크로소프트 Windows INI 파일에서 볼 수 있는 것과 비슷한 구조를 제공하는 기본 설정 언어를 구현하는 ConfigParser 클래스를 제공해요. 이걸로 최종 사용자가 쉽게 커스터마이즈할 수 있는 파이썬 프로그램을 쓸 수 있어요.

참고: 이 라이브러리는 Windows 레지스트리 확장 버전의 INI 문법에 쓰이는 값-타입 접두사를 해석하거나 쓰지 않아요.

참고: tomllib 모듈(TOML은 애플리케이션 설정 파일을 위해 잘 명세된 형식으로 INI의 개선판으로 설계됨), shlex 모듈(셸 같은 미니 언어 생성), json 모듈(주석을 지원하지 않는 설정 형식)도 함께 보세요.

출처: Python documentation

본문

빠른 시작 (Quick Start)

아주 기본적인 설정 파일을 보면:

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
[forge.example]
User = hg
[topsecret.server.example]
Port = 50022
ForwardX11 = no

INI 파일 구조는 다음 절에서 설명해요. 본질적으로 파일은 섹션(section) 들로 이뤄지고, 각 섹션은 값이 있는 키(key) 들을 담아요. configparser 클래스는 그런 파일을 읽고 쓸 수 있어요. 이 설정 파일을 프로그램적으로 만들어 볼게요.

>>> import configparser
>>> config = configparser.ConfigParser()
>>> config['DEFAULT'] = {'ServerAliveInterval': '45',
...                      'Compression': 'yes',
...                      'CompressionLevel': '9'}
>>> config['forge.example'] = {}
>>> config['forge.example']['User'] = 'hg'
>>> config['topsecret.server.example'] = {}
>>> topsecret = config['topsecret.server.example']
>>> topsecret['Port'] = '50022'     # mutates the parser
>>> with open('example.ini', 'w') as configfile:
...   config.write(configfile)

config parser를 사전처럼 다룰 수 있어요. 다시 읽어 보면:

>>> config = configparser.ConfigParser()
>>> config.sections()
[]
>>> config.read('example.ini')
['example.ini']
>>> config.sections()
['forge.example', 'topsecret.server.example']
>>> config['forge.example']['User']
'hg'
>>> topsecret['ForwardX11']
'no'
>>> config['forge.example']['ForwardX11']
'yes'

API는 꽤 직관적이에요. 유일한 마법은 다른 모든 섹션에 기본값을 제공하는 DEFAULT 섹션이에요 [1]. 섹션의 키는 대소문자를 구분하지 않고 소문자로 저장돼요 [1].

여러 설정을 하나의 ConfigParser로 읽을 수 있는데, 가장 최근에 추가된 설정이 가장 높은 우선순위를 가져요. 충돌하는 키는 더 최근 설정에서 가져오고 기존 키는 유지돼요.

지원되는 데이터 타입 (Supported Datatypes)

Config 파서는 설정 파일의 값 데이터 타입을 추측하지 않고 항상 내부적으로 문자열로 저장해요. 다른 타입이 필요하면 직접 변환해야 해요 (int(topsecret['Port'])). 이 작업이 흔해서 파서는 정수·부동소수점·불리언을 다루는 getter 메서드들을 제공해요. 특히 getboolean()bool('False')가 여전히 True이므로 값만 bool()에 넘기는 건 소용없기 때문에 흥미로워요. getboolean()은 대소문자 무시하고 'yes'/'no', 'on'/'off', 'true'/'false', '1'/'0'을 불리언으로 인식해요. getint()getfloat()도 있고, 고유 converter를 등록할 수도 있어요 [1].

대체 값 (Fallback Values)

사전처럼 섹션의 get() 메서드로 대체 값을 제공할 수 있어요. topsecret.get('Cipher', '3des-cbc')는 'Cipher'가 없으면 '3des-cbc'를 반환해요. 기본값이 대체 값보다 우선한다는 점에 주의하세요. 예를 들어 'CompressionLevel' 키는 'DEFAULT' 섹션에만 있어서, 'topsecret.server.example' 섹션에서 가져오려 하면 대체 값을 지정해도 항상 기본값을 얻어요 (.get('CompressionLevel', '3') → '9'). 파서 수준 get()fallback 키워드 인자로 대체 값을 제공하는 더 복잡한 인터페이스예요.

지원되는 INI 파일 구조 (Supported INI File Structure)

설정 파일은 각각 [section] 헤더로 시작하는 섹션들로 이뤄지고, 그 뒤에 특정 문자열(기본 = 또는 :)로 구분되는 key/value 항목이 따라와요 [1]. 기본적으로 섹션 이름은 대소문자를 구분하지만 키는 아니에요 [1]. 키와 값의 앞뒤 공백은 제거돼요. 값은 값의 첫 줄보다 더 깊게 들여쓰기되면 여러 줄에 걸칠 수 있어요. 기본적으로 유효한 섹션 이름은 '\n'을 포함하지 않는 어떤 문자열이든 돼요 (ConfigParser.SECTCRE로 변경).

allow_unnamed_section=True로 파서를 구성하면 첫 섹션 이름을 생략할 수 있고, 키/값은 config[UNNAMED_SECTION]처럼 가져올 수 있어요.

설정 파일은 특정 문자(기본 #;)로 접두된 주석을 포함할 수 있어요 [1]. 주석은 비어 있는 줄(들여쓰기 가능)에 있어요.

값 보간 (Interpolation of values)

핵심 기능 위에 ConfigParser보간(interpolation) 을 지원해요. 즉 get() 호출에서 반환하기 전에 값을 전처리할 수 있다는 뜻이에요.

  • class configparser.BasicInterpolation: ConfigParser가 쓰는 기본 구현. 값이 같은 섹션이나 특수 기본 섹션의 다른 값을 참조하는 형식 문자열을 포함할 수 있게 해요 [1]. %(home_dir)s 같은 참조를 해결하고, %를 이스케이프하려면 %%를 써요. 모든 보간은 요청 시(on demand) 이뤄져 참조 체인의 키가 파일에서 특정 순서일 필요가 없어요.
  • class configparser.ExtendedInterpolation: zc.buildout 등에서 쓰는 더 고급 문법을 구현하는 대체 핸들러. ${section:option}으로 다른 섹션의 값을 나타내요. 보간이 여러 수준에 걸칠 수 있어요. 편의상 section:을 생략하면 현재 섹션(그리고 특수 섹션의 기본값)으로 기본 설정돼요. $를 이스케이프하려면 $$를 써요.

매핑 프로토콜 접근 (Mapping Protocol Access)

(3.2 추가) 매핑 인터페이스는 사용자 정의 객체를 사전인 것처럼 쓰는 것을 가능하게 해 줘요. configparser에서 parser['section']['option'] 표기를 사용해요. parser['section']은 섹션 데이터의 프록시를 반환하고, 값은 복사되지 않고 원본 파서에서 요청 시 가져와요. 더 중요한 것은 섹션 프록시에서 값을 바꾸면 실제로 원본 파서에서 변경된다는 점이에요.

configparser 객체는 실제 사전에 가능한 한 가깝게 동작하고, 매핑 인터페이스는 MutableMapping ABC를 준수해요. 하지만 몇 가지 차이가 있어요:

  • 기본적으로 섹션의 모든 키는 대소문자를 무시하고 접근 가능해요. parser["section"]을 순회하면 optionxform 된(기본 소문자) 키 이름이 나와요.
  • 모든 섹션은 DEFAULTSECT 값을 포함하므로 섹션에 .clear()를 해도 눈에 띄게 비어 보이지 않을 수 있어요. 기본값은 섹션에서 삭제할 수 없어요(기술적으로 거기 없으니까). 섹션에서 기본값을 오버라이드한 경우 삭제하면 기본값이 다시 보여요.
  • DEFAULTSECT는 파서에서 제거할 수 없어요: 삭제하려 하면 ValueError, parser.clear()는 그대로 두고, parser.popitem()은 절대 반환하지 않아요.
  • parser.items()는 매핑 프로토콜과 호환되고(섹션 이름, 섹션 프록시 쌍의 리스트를 DEFAULTSECT 포함해 반환), 인자와 함께 호출하면(parser.items(section, raw, vars)) 지정 섹션의 옵션·값 쌍을 모든 보간이 확장된 채로 반환해요.

파서 동작 커스터마이즈 (Customizing Parser Behaviour)

INI 형식 변형은 그것을 쓰는 애플리케이션만큼 많아요. 동작을 바꾸는 가장 흔한 방법은 __init__() 옵션이에요.

  • defaults, 기본 None: DEFAULT 섹션에 처음 넣을 키-값 쌍의 사전.
  • dict_type, 기본 dict: 매핑 프로토콜 동작과 작성된 설정 파일 모양에 큰 영향을 줘요. 대안 사전 타입으로 섹션·옵션을 정렬할 수 있어요.
  • allow_no_value, 기본 False: 값이 없는 설정을 허용할지 (예: MySQL 설정의 skip-bdb). 값이 없는 설정은 None을 반환해요.
  • delimiters, 기본 ('=', ':'): 섹션 안에서 키와 값을 구분하는 부분 문자열. 줄에서 구분 문자열의 첫 발생이 구분자로 간주돼 값(키는 아님)이 구분자를 포함할 수 있어요.
  • comment_prefixes, 기본 ('#', ';')와 inline_comment_prefixes, 기본 None: 주석 시작을 나타내는 문자열. comment_prefixes는 (선택적으로 들여쓰기된) 비어 있는 줄에만, inline_comment_prefixes는 모든 유효한 값 뒤에 쓸 수 있어요. 기본적으로 인라인 주석은 비활성화되고 '#'와 ';'가 전체 줄 주석 접두사로 쓰여요. 파서는 주석 접두사 이스케이프를 지원하지 않아 주의가 필요해요.
  • strict, 기본 True: True면 단일 소스에서 읽을 때 섹션 또는 옵션 중복을 허용하지 않아요. 새 애플리케이션에선 strict 파서 사용을 권장해요.
  • empty_lines_in_values, 기본 True: 값이 여러 줄에 걸칠 수 있고 빈 줄도 값의 일부일 수 있어요. 애플리케이션이 빈 줄 있는 값을 필요로 하지 않으면 비활성화하는 걸 고려하세요 (빈 줄이 키를 분리하게 됨).
  • default_section, 기본 "DEFAULT": 다른 섹션의 기본값을 위한 특수 섹션의 이름. "general"이나 "common" 같은 값으로 바꿀 수 있어요.
  • interpolation, 기본 configparser.BasicInterpolation: 커스텀 핸들러를 interpolation 인자로 제공해 보간 동작을 커스터마이즈. None은 보간을 완전히 끄고, ExtendedInterpolation()은 더 고급 변형. RawConfigParser의 기본값은 None이에요.
  • converters, 기본 미설정: 파서와 모든 섹션 프록시에 실행되는 getter를 추가. 예를 들어 {'decimal': decimal.Decimal}을 넘기면 getdecimal()이 추가돼요.
  • ConfigParser.BOOLEAN_STATES: 기본으로 getboolean()은 '1','yes','true','on'을 True, '0','no','false','off'를 False로 간주. 커스텀 사전을 지정해 오버라이드할 수 있어요.
  • ConfigParser.optionxform(option): 모든 read/get/set 연산에서 옵션 이름을 변환. 기본은 소문자로 변환(그래서 파일 작성 시 모든 키가 소문자). 다른 동작을 원하면 오버라이드. optionxform = str로 만들면 대소문자 구분. optionxform은 멱등 함수여야 해요.

ConfigParser 객체 메서드

  • read(filenames, encoding=None): 파일 이름 목록을 읽고 성공적으로 읽은 파일 이름 목록 반환.
  • read_file(f, source=None), read_string(string, source='<string>'), read_dict(dictionary, source='<dict>'): 다양한 소스에서 읽기.
  • get(section, option, *, raw=False, vars=None[, fallback]): 옵션 값 반환. raw가 false면 모든 '%' 보간이 확장돼요.
  • getint(...), getfloat(...), getboolean(...): 타입 변환 편의 메서드.
  • items(raw=False, vars=None) / items(section, raw=False, vars=None): 섹션 없이 호출하면 (섹션 이름, 섹션 프록시) 쌍 리스트 반환 (DEFAULTSECT 포함), 섹션 지정 시 옵션·값 쌍 리스트.
  • set(section, option, value): 옵션 값 설정 (섹션이 없으면 NoSectionError).
  • write(fileobject, space_around_delimiters=True): 설정 표현을 파일 객체(텍스트 모드)에 작성. space_around_delimiters가 true면 키/값 사이 구분자를 공백으로 감싸요. 3.14부터 미래 read() 호출로 정확히 파싱되지 않을 표현을 작성하면 InvalidWriteError를 발생.
  • remove_option(section, option), remove_section(section): 항목 제거.
  • optionxform(option): 위 참고.
  • configparser.UNNAMED_SECTION: 이름 없는 섹션을 참조하는 특수 객체.
  • configparser.MAX_INTERPOLATION_DEPTH: raw가 false일 때 get()의 재귀 보간 최대 깊이.

RawConfigParser 객체

class configparser.RawConfigParser(...): ConfigParser의 레거시 변형. 기본으로 보간이 비활성화돼 있고, add_sectionset 메서드, 그리고 레거시 defaults= 키워드 인자 처리를 통해 비문자열 섹션 이름·옵션 이름·값을 허용해요. 보간이 필요 없으면 ConfigParser(interpolation=None)을 쓰는 게 낫다는 점을 권장해요.

  • add_section(section): section 또는 UNNAMED_SECTION 추가. 이미 있으면 DuplicateSectionError. 기본 섹션 이름이면 ValueError. UNNAMED_SECTION이고 지원이 비활성화면 UnnamedSectionDisabledError. (3.14부터 UNNAMED_SECTION 지원)

예외 (Exceptions)

  • exception configparser.Error: 다른 모든 configparser 예외의 기본 클래스.
  • exception configparser.NoSectionError: 지정 섹션을 찾지 못할 때.
  • exception configparser.DuplicateSectionError: add_section()이 이미 있는 섹션 이름으로 호출되거나, strict 파서에서 단일 입력 파일·문자열·사전에 섹션이 두 번 이상 발견될 때.
  • exception configparser.DuplicateOptionError: strict 파서에서 단일 파일·문자열·사전에서 옵션이 두 번 나타날 때.
  • exception configparser.NoOptionError: 지정 섹션에서 지정 옵션을 찾지 못할 때.
  • exception configparser.InterpolationError: 문자열 보간 문제 시 기본 클래스.
  • exception configparser.InterpolationDepthError: 반복 횟수가 MAX_INTERPOLATION_DEPTH를 초과해 보간을 완료할 수 없을 때.
  • exception configparser.InterpolationMissingOptionError: 값에서 참조된 옵션이 존재하지 않을 때.
  • exception configparser.InterpolationSyntaxError: 치환할 소스 텍스트가 요구 문법을 따르지 않을 때.
  • exception configparser.MissingSectionHeaderError: 섹션 헤더가 없는 파일을 파싱하려 할 때.
  • exception configparser.ParsingError: 파일 파싱 중 오류가 발생할 때.
  • exception configparser.MultilineContinuationError: 대응하는 값이 없는 키가 들여쓰기된 줄로 계속될 때. (3.13)
  • exception configparser.UnnamedSectionDisabledError: 활성화하지 않고 UNNAMED_SECTION을 사용하려 할 때. (3.14)
  • exception configparser.InvalidWriteError: ConfigParser.write()로 쓰려는 것이 미래 ConfigParser.read() 호출로 정확히 파싱되지 않을 때. 예: SECTCRE 패턴으로 시작하는 키를 쓰면 읽을 때 섹션 헤더로 파싱돼요. (3.14)

더 알아보기 (Learn more)