"configparser" --- 구성 파일 구문 분석기
****************************************

**소스 코드:** Lib/configparser.py

======================================================================

이 모듈은 마이크로소프트 윈도우 INI 파일과 유사한 구조를 제공하는 기본
구성 언어를 구현하는 "ConfigParser" 클래스를 제공합니다. 이를 사용하여
최종 사용자가 쉽게 사용자 정의 할 수 있는 파이썬 프로그램을 작성할 수
있습니다.

참고:

  이 라이브러리는 윈도우 레지스트리 확장 버전의 INI 문법에 사용된 값-
  형 접두사를 해석하거나 기록하지 *않습니다*.

더 보기:

  모듈 "tomllib"
     TOML is a well-specified format for application configuration
     files. It is specifically designed to be an improved version of
     INI.

  모듈 "shlex"
     응용 프로그램 구성 파일에도 사용할 수 있는 유닉스 셸과 유사한 미
     니 언어를 만드는 것에 관한 지원.

  모듈 "json"
     "json" 모듈은 자바스크립트 문법의 부분 집합을 구현하며, 때로는 구
     성에 사용되지만 주석을 지원하지 않습니다.


빠른 시작
=========

다음과 같은 매우 기본적인 구성 파일을 봅시다:

   [DEFAULT]
   ServerAliveInterval = 45
   Compression = yes
   CompressionLevel = 9
   ForwardX11 = yes

   [forge.example]
   User = hg

   [topsecret.server.example]
   Port = 50022
   ForwardX11 = no

INI 파일의 구조는 다음 섹션에서 설명됩니다. 기본적으로, 파일은 섹션으
로 구성되며, 각 섹션에는 값이 있는 키가 포함됩니다. "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'     # 구문 분석기를 변경합니다
   >>> topsecret['ForwardX11'] = 'no'  # 여기도 마찬가지입니다
   >>> config['DEFAULT']['ForwardX11'] = 'yes'
   >>> with open('example.ini', 'w') as configfile:
   ...   config.write(configfile)
   ...

보시다시피, 구성 구문 분석기는 딕셔너리처럼 취급할 수 있습니다. 나중에
설명되는 차이점이 있지만, 동작은 딕셔너리에서 기대하는 것과 매우 비슷
합니다.

이제 구성 파일을 만들고 저장했으니, 파일을 다시 읽고 담긴 데이터를 탐
색합시다.

   >>> config = configparser.ConfigParser()
   >>> config.sections()
   []
   >>> config.read('example.ini')
   ['example.ini']
   >>> config.sections()
   ['forge.example', 'topsecret.server.example']
   >>> 'forge.example' in config
   True
   >>> 'python.org' in config
   False
   >>> config['forge.example']['User']
   'hg'
   >>> config['DEFAULT']['Compression']
   'yes'
   >>> topsecret = config['topsecret.server.example']
   >>> topsecret['ForwardX11']
   'no'
   >>> topsecret['Port']
   '50022'
   >>> for key in config['forge.example']:
   ...     print(key)
   user
   compressionlevel
   serveraliveinterval
   compression
   forwardx11
   >>> config['forge.example']['ForwardX11']
   'yes'

위에서 볼 수 있듯이, API는 매우 간단합니다. 유일한 마법은 "DEFAULT" 섹
션인데, 다른 모든 섹션에 대한 기본값을 제공합니다 [1]. 섹션의 키는 대
소 문자를 구분하지 않으며 소문자로 저장됨에 유의하십시오 [1].

It is possible to read several configurations into a single
"ConfigParser", where the most recently added configuration has the
highest priority. Any conflicting keys are taken from the more recent
configuration while the previously existing keys are retained. The
example below reads in an "override.ini" file, which will override any
conflicting keys from the "example.ini" file.

   [DEFAULT]
   ServerAliveInterval = -1

   >>> config_override = configparser.ConfigParser()
   >>> config_override['DEFAULT'] = {'ServerAliveInterval': '-1'}
   >>> with open('override.ini', 'w') as configfile:
   ...     config_override.write(configfile)
   ...
   >>> config_override = configparser.ConfigParser()
   >>> config_override.read(['example.ini', 'override.ini'])
   ['example.ini', 'override.ini']
   >>> print(config_override.get('DEFAULT', 'ServerAliveInterval'))
   -1

This behaviour is equivalent to a "ConfigParser.read()" call with
several files passed to the *filenames* parameter.


지원되는 데이터형
=================

구성 구문 분석기는 구성 파일에 있는 값의 데이터형을 추측하지 않고, 항
상 내부적으로 문자열로 저장합니다. 이것은 다른 데이터형이 필요하면, 직
접 변환해야 함을 뜻합니다:

   >>> int(topsecret['Port'])
   50022
   >>> float(topsecret['CompressionLevel'])
   9.0

이 작업이 매우 흔하기 때문에, 구성 구문 분석기는 정수, 부동 소수점 및
불리언을 처리하는 편리한 게터(getter) 메서드를 제공합니다. 마지막 것이
가장 흥미로운데, "bool('False')" 가 여전히 "True"이기 때문에 "bool()"
에 값을 전달하는 것만으로는 충분치 않기 때문입니다. 이것이 구성 구문
분석기가 "getboolean()"도 제공하는 이유입니다. 이 메서드는 대소 문자를
구분하지 않으며 "'yes'"/"'no'", "'on'"/"'off'", "'true'"/"'false'" 및
"'1'"/"'0'"에서 불리언 값을 인식합니다 [1]. 예를 들면:

   >>> topsecret.getboolean('ForwardX11')
   False
   >>> config['forge.example'].getboolean('ForwardX11')
   True
   >>> config.getboolean('forge.example', 'Compression')
   True

"getboolean()" 외에도, 구성 구문 분석기는 동등한 "getint()"와
"getfloat()" 메서드를 제공합니다. 여러분 자신의 변환기를 등록하고 제공
된 변환기를 사용자 정의 할 수 있습니다. [1]


대체 값
=======

딕셔너리와 마찬가지로, 섹션의 "get()" 메서드를 사용하여 대체(fallback)
값을 제공할 수 있습니다:

   >>> topsecret.get('Port')
   '50022'
   >>> topsecret.get('CompressionLevel')
   '9'
   >>> topsecret.get('Cipher')
   >>> topsecret.get('Cipher', '3des-cbc')
   '3des-cbc'

기본값이 대체 값보다 우선함에 유의하십시오. 예를 들어, 이 예에서
"'CompressionLevel'" 키는 "'DEFAULT'" 섹션에서만 지정되었습니다. 이것
을 "'topsecret.server.example'" 섹션에서 가져오려고 하면 대체 값을 지
정하더라도 항상 기본값을 얻습니다:

   >>> topsecret.get('CompressionLevel', '3')
   '9'

알아 두어야 할 또 다른 사항은 구문 분석기 수준의 "get()" 메서드가 이전
버전과의 호환성을 위해 유지되는 더 복잡한 사용자 정의 인터페이스를 제
공한다는 것입니다. 이 메서드를 사용할 때, "fallback" 키워드 전용 인자
를 통해 대체 값을 제공할 수 있습니다:

   >>> config.get('forge.example', 'monster',
   ...            fallback='No such things as monsters')
   'No such things as monsters'

"getint()", "getfloat()" 및 "getboolean()" 메서드에 같은 "fallback" 인
자를 사용할 수 있습니다. 예를 들면:

   >>> 'BatchMode' in topsecret
   False
   >>> topsecret.getboolean('BatchMode', fallback=True)
   True
   >>> config['DEFAULT']['BatchMode'] = 'no'
   >>> topsecret.getboolean('BatchMode', fallback=True)
   False


지원되는 INI 파일 구조
======================

구성 파일은 섹션으로 구성되며, 각 섹션은 "[section]" 헤더로 시작하고,
특정 문자열(기본적으로 "="이나 ":" [1])로 구분된 키/값 항목들이 뒤따릅
니다. 기본적으로, 섹션 이름은 대소 문자를 구분하지만 키는 구분하지 않
습니다 [1]. 선행과 후행 공백은 키와 값에서 제거됩니다. 구문 분석기가
이를 허용하도록 구성되어 있다면 값을 생략할 수 있으며 [1], 이 경우 키/
값 구분자도 생략될 수 있습니다. 값의 첫 줄보다 깊이 들여쓰기만 하면 값
이 여러 줄에 걸쳐있을 수 있습니다. 구문 분석기의 모드에 따라, 빈 줄은
여러 줄 값의 일부로 취급되거나 무시될 수 있습니다.

By default, a valid section name can be any string that does not
contain '\n'. To change this, see "ConfigParser.SECTCRE".

The first section name may be omitted if the parser is configured to
allow an unnamed top level section with "allow_unnamed_section=True".
In this case, the keys/values may be retrieved by "UNNAMED_SECTION" as
in "config[UNNAMED_SECTION]".

구성 파일에는 특정 문자(기본적으로 "#"과 ";" [1])를 접두사로 붙인 주석
이 포함될 수 있습니다. 주석은 주석이 없다면 빈 줄일 곳에 있을 수 있으
며, 들여쓰기 될 수 있습니다. [1]

예를 들면:

   [Simple Values]
   key=value
   spaces in keys=allowed
   spaces in values=allowed as well
   spaces around the delimiter = obviously
   you can also use : to delimit keys from values

   [All Values Are Strings]
   values like this: 1000000
   or this: 3.14159265359
   are they treated as numbers? : no
   integers, floats and booleans are held as: strings
   can use the API to get converted values directly: true

   [Multiline Values]
   chorus: I'm a lumberjack, and I'm okay
       I sleep all night and I work all day

   [No Values]
   key_without_value
   empty string value here =

   [You can use comments]
   # 이것처럼
   ; 또는 이것처럼

   # 기본적으로 빈 줄에만 허용됩니다.
   # 인라인 주석은 사용자가 구분 문자를 값의 일부로
   # 사용하지 못하게 하므로 해로울 수 있습니다.
   # 그러해도, 이것을 사용자 정의할 수 있습니다.

       [Sections Can Be Indented]
           can_values_be_as_well = True
           does_that_mean_anything_special = False
           purpose = formatting for readability
           multiline_values = are
               handled just fine as
               long as they are indented
               deeper than the first line
               of a value
           # 주석도 들여 쓸 수 있다고 언급했나요?


Unnamed Sections
================

The name of the first section (or unique) may be omitted and values
retrieved by the "UNNAMED_SECTION" attribute.

   >>> config = """
   ... option = value
   ...
   ... [  Section 2  ]
   ... another = val
   ... """
   >>> unnamed = configparser.ConfigParser(allow_unnamed_section=True)
   >>> unnamed.read_string(config)
   >>> unnamed.get(configparser.UNNAMED_SECTION, 'option')
   'value'


값의 보간
=========

핵심 기능 위에, "ConfigParser"는 보간(interpolation)을 지원합니다. 이
는 "get()" 호출에서 값을 반환하기 전에 값을 전처리할 수 있음을 의미합
니다.

class configparser.BasicInterpolation

   "ConfigParser"에서 사용되는 기본 구현. 같은 섹션의 다른 값이나 특수
   한 기본 섹션의 값을 참조하는 포맷 문자열을 포함하는 값을 사용할 수
   있도록 합니다 [1]. 초기화할 때 추가 기본값을 제공할 수 있습니다.

   예를 들면:

      [Paths]
      home_dir: /Users
      my_dir: %(home_dir)s/lumberjack
      my_pictures: %(my_dir)s/Pictures

      [Escape]
      # %% 를 사용하여 % 기호를 이스케이프 합니다 (% 는 이스케이프 해야 하는 유일한 문자입니다):
      gain: 80%%

   위의 예에서, *interpolation*이 "BasicInterpolation()" 으로 설정된
   "ConfigParser"는 "%(home_dir)s"를 "home_dir"의 값(이 경우 "/Users")
   으로 해석합니다. 결과적으로 "%(my_dir)s"는 "/Users/lumberjack"으로
   해석됩니다. 모든 보간은 요청 시 수행되므로 참조 체인에 사용된 키를
   구성 파일에서 특정 순서로 지정할 필요는 없습니다.

   "interpolation"을 "None"으로 설정하면, 구문 분석기는 "my_pictures"
   의 값을 "%(my_dir)s/Pictures"로, "my_dir"의 값을
   "%(home_dir)s/lumberjack"으로 반환합니다.

class configparser.ExtendedInterpolation

   예를 들어 "zc.buildout"에서 사용되는 고급 문법을 구현하는 보간 대체
   처리기. 확장 보간은 "${section:option}"을 사용하여 외부 섹션의 값을
   나타냅니다. 보간은 여러 수준으로 확장될 수 있습니다. 편의상,
   "section:" 부분을 생략하면, 보간은 현재 섹션(그리고 가능하면 특수
   섹션의 기본값)으로 기본 설정됩니다.

   예를 들어, 기본 보간으로 위에서 지정한 구성은, 확장 보간으로는 다음
   과 같습니다:

      [Paths]
      home_dir: /Users
      my_dir: ${home_dir}/lumberjack
      my_pictures: ${my_dir}/Pictures

      [Escape]
      # $$ 를 사용하여 $ 기호를 이스케이프 합니다 ($ 는 이스케이프 해야 하는 유일한 문자입니다):
      cost: $$80

   다른 섹션의 값도 가져올 수 있습니다:

      [Common]
      home_dir: /Users
      library_dir: /Library
      system_dir: /System
      macports_dir: /opt/local

      [Frameworks]
      Python: 3.2
      path: ${Common:system_dir}/Library/Frameworks/

      [Arthur]
      nickname: Two Sheds
      last_name: Jackson
      my_dir: ${Common:home_dir}/twosheds
      my_pictures: ${my_dir}/Pictures
      python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}


매핑 프로토콜 액세스
====================

Added in version 3.2.

매핑 프로토콜 액세스는 사용자 정의 객체를 딕셔너리처럼 사용하는 기능의
일반적인 이름입니다. "configparser"의 경우, 매핑 인터페이스 구현은
"parser['section']['option']" 표기법을 사용합니다.

"parser['section']"은 특히 구문 분석기의 섹션 데이터에 대한 프락시를
반환합니다. 이는 값은 복사되지 않지만 필요할 때 원래 구문 분석기에서
가져옴을 뜻합니다. 더욱 중요한 것은 섹션 프락시에서 값이 변경되면, 실
제로 원래 구문 분석기에서 변경된다는 것입니다.

"configparser" 객체는 가능한 한 실제 딕셔너리에 가깝게 동작합니다. 매
핑 인터페이스가 완전하며 "MutableMapping" ABC를 준수합니다. 그러나, 고
려해야 하는 몇 가지 차이점이 있습니다:

* 기본적으로, 섹션의 모든 키는 대소 문자를 구분하지 않고 액세스 할 수
  있습니다 [1]. 예를 들어 "for option in parser["section"]"는
  "optionxform" 변환된 옵션 키 이름만 산출합니다. 이것은 기본적으로 소
  문자 키를 의미합니다. 동시에, 키 "'a'"를 보유하는 섹션의 경우, 두 표
  현식 모두 "True"를 반환합니다:

     "a" in parser["section"]
     "A" in parser["section"]

* 모든 섹션에는 "DEFAULTSECT" 값도 포함되어 있는데, 섹션에 대한
  ".clear()"가 섹션을 비어 보이게 만들 수 없다는 뜻입니다. 이것은 섹션
  에서 기본값을 삭제할 수 없기 때문입니다 (기술적으로는 기본값이 거기
  없기 때문입니다). 섹션에서 재정의되었으면, 삭제하면 기본값이 다시 보
  입니다. 기본값을 삭제하려고 하면 "KeyError"가 발생합니다.

* "DEFAULTSECT"는 구문 분석기에서 제거할 수 없습니다:

  * 삭제하려고 하면 "ValueError"가 발생합니다,

  * "parser.clear()"는 이것을 그대로 남겨둡니다,

  * "parser.popitem()"은 이것을 절대 반환하지 않습니다.

* "parser.get(section, option, **kwargs)" - 두 번째 인자는 대체 값이
  **아닙니다**. 그러나 섹션 수준 "get()" 메서드는 매핑 프로토콜과 클래
  식 configparser API와 모두 호환됨에 유의하십시오.

* "parser.items()"는 매핑 프로토콜과 호환됩니다 (DEFAULTSECT를 포함하
  여 *section_name*, *section_proxy* 쌍의 리스트를 반환합니다). 그러나
  , 이 메서드는 인자와 함께 호출 할 수도 있습니다:
  "parser.items(section, raw, vars)". 후자의 호출은 지정된 "section"에
  대한 *option*, *value* 쌍의 리스트를 반환하며, 모든 보간이 확장됩니
  다 ("raw=True"가 제공되지 않는 한).

매핑 프로토콜은 기존 레거시 API 위에 구현되므로 원래 인터페이스를 재정
의하는 서브 클래스에서도 여전히 매핑이 작동해야 합니다.


구문 분석기 동작 사용자 정의
============================

INI 형식을 사용하는 응용 프로그램만큼이나 많은 INI 형식 변형이 있습니
다. "configparser"는 사용 가능한 가장 큰 INI 스타일 집합을 지원하기 위
해 먼 길을 갔습니다. 기본 기능은 주로 역사적 배경에 의해 결정되며 일부
기능을 사용자 정의하고 싶을 가능성이 큽니다.

특정 구성 구문 분석기의 작동 방식을 변경하는 가장 흔한 방법은
"__init__()" 옵션을 사용하는 것입니다:

* *defaults*, 기본값: "None"

  이 옵션은 처음에 "DEFAULT" 섹션에 배치될 키-값 쌍의 딕셔너리를 받아
  들입니다. 이것은 지정하지 않으면 설명된 기본값과 같은 값이 되는 간결
  한 구성 파일을 지원하는 우아한 방법입니다.

  힌트: 특정 섹션에 대한 기본값을 지정하려면, 실제 파일을 읽기 전에
  "read_dict()"를 사용하십시오.

* *dict_type*, 기본값: "dict"

  이 옵션은 매핑 프로토콜의 작동 방식과 기록된 구성 파일의 꼴에 큰 영
  향을 미칩니다. 표준 딕셔너리를 사용하면, 모든 섹션이 구문 분석기에
  추가된 순서대로 저장됩니다. 섹션 내의 옵션도 마찬가지입니다.

  대체 딕셔너리 형을 사용하여 예를 들어 다시 쓸 때 섹션과 옵션을 정렬
  할 수 있습니다.

  참고: 단일 연산에서 키-값 쌍의 집합을 추가하는 방법이 있습니다. 이러
  한 연산에서 일반 딕셔너리를 사용하면 키 순서가 유지됩니다. 예를 들면
  :

     >>> parser = configparser.ConfigParser()
     >>> parser.read_dict({'section1': {'key1': 'value1',
     ...                                'key2': 'value2',
     ...                                'key3': 'value3'},
     ...                   'section2': {'keyA': 'valueA',
     ...                                'keyB': 'valueB',
     ...                                'keyC': 'valueC'},
     ...                   'section3': {'foo': 'x',
     ...                                'bar': 'y',
     ...                                'baz': 'z'}
     ... })
     >>> parser.sections()
     ['section1', 'section2', 'section3']
     >>> [option for option in parser['section3']]
     ['foo', 'bar', 'baz']

* *allow_no_value*, 기본값: "False"

  일부 구성 파일에는 값이 없는 설정이 포함되어 있지만, 그 외에는
  "configparser" 에서 지원하는 구문을 준수하는 것으로 알려져 있습니다.
  생성자에 대한 *allow_no_value* 매개 변수를 사용하여 이러한 값을 받아
  들여야 함을 표시할 수 있습니다:

     >>> import configparser

     >>> sample_config = """
     ... [mysqld]
     ...   user = mysql
     ...   pid-file = /var/run/mysqld/mysqld.pid
     ...   skip-external-locking
     ...   old_passwords = 1
     ...   skip-bdb
     ...   # we don't need ACID today
     ...   skip-innodb
     ... """
     >>> config = configparser.ConfigParser(allow_no_value=True)
     >>> config.read_string(sample_config)

     >>> # 값이 있는 설정은 이전처럼 처리됩니다:
     >>> config["mysqld"]["user"]
     'mysql'

     >>> # 값이 없는 설정은 None을 제공합니다:
     >>> config["mysqld"]["skip-bdb"]

     >>> # 지정되지 않은 설정은 여전히 에러를 발생시킵니다:
     >>> config["mysqld"]["does-not-exist"]
     Traceback (most recent call last):
       ...
     KeyError: 'does-not-exist'

* *delimiters*, 기본값: "('=', ':')"

  구분자(delimiters)는 섹션 내의 값에서 키를 구분하는 부분 문자열입니
  다. 줄에서 처음 나타나는 구분하는 부분 문자열을 구분자로 간주합니다.
  이는 값에 (하지만 키는 아닙니다) 구분자가 포함될 수 있음을 의미합니
  다.

  "ConfigParser.write()"에 대한 *space_around_delimiters* 인자도 참조
  하십시오.

* *comment_prefixes*, 기본값: "('#', ';')"

* *inline_comment_prefixes*, 기본값 : "None"

  주석 접두사는 구성 파일 내에서 유효한 주석의 시작을 나타내는 문자열
  입니다. *comment_prefixes*는 주석이 없으면 빈 줄일 때만 (선택적으로
  들여쓰기 됩니다) 사용되는 반면  *inline_comment_prefixes*는 모든 유
  효한 값 (예를 들어 섹션 이름, 옵션 및 빈 줄 역시) 뒤에 사용될 수 있
  습니다. 기본적으로 인라인 주석은 비활성화되어 있으며 "'#'"과 "';'"이
  전체 줄 주석의 접두사로 사용됩니다.

  버전 3.2에서 변경: "configparser"의 이전 버전에서는 동작이
  "comment_prefixes=('#',';')"와 "inline_comment_prefixes=(';',)"와 일
  치했습니다.

  구성 구문 분석기는 주석 접두사 이스케이프를 지원하지 않아서
  *inline_comment_prefixes*를 사용하면 사용자가 주석 접두사로 사용되는
  문자로 옵션값을 지정하지 못할 수 있습니다. 확실하지 않으면,
  *inline_comment_prefixes*를 설정하지 마십시오. 어떤 상황에서든, 여러
  줄 값에서 줄의 시작 부분에 주석 접두사 문자를 저장하는 유일한 방법은
  접두사를 보간하는 것입니다, 예를 들어:

     >>> from configparser import ConfigParser, ExtendedInterpolation
     >>> parser = ConfigParser(interpolation=ExtendedInterpolation())
     >>> # the default BasicInterpolation could be used as well
     >>> parser.read_string("""
     ... [DEFAULT]
     ... hash = #
     ...
     ... [hashes]
     ... shebang =
     ...   ${hash}!/usr/bin/env python
     ...   ${hash} -*- coding: utf-8 -*-
     ...
     ... extensions =
     ...   enabled_extension
     ...   another_extension
     ...   #disabled_by_comment
     ...   yet_another_extension
     ...
     ... interpolation not necessary = if # is not at line start
     ... even in multiline values = line #1
     ...   line #2
     ...   line #3
     ... """)
     >>> print(parser['hashes']['shebang'])

     #!/usr/bin/env python
     # -*- coding: utf-8 -*-
     >>> print(parser['hashes']['extensions'])

     enabled_extension
     another_extension
     yet_another_extension
     >>> print(parser['hashes']['interpolation not necessary'])
     if # is not at line start
     >>> print(parser['hashes']['even in multiline values'])
     line #1
     line #2
     line #3

* *strict*, 기본값: "True"

  "True"로 설정하면, 구문 분석기는 단일 소스에서 읽는 ("read_file()",
  "read_string()" 또는 "read_dict()"를 사용해서) 동안 섹션이나 옵션 중
  복을 허용하지 않습니다. 새로운 응용 프로그램에서는 엄격한(strict) 구
  문 분석기를 사용하는 것이 좋습니다.

  버전 3.2에서 변경: "configparser"의 이전 버전에서는 동작이
  "strict=False"와 일치했습니다.

* *empty_lines_in_values*, 기본값: "True"

  구성 구문 분석기에서는, 값을 담는 키보다 많이 들여쓰기만 하면 값이
  여러 줄에 걸쳐있을 수 있습니다. 기본적으로 구문 분석기는 빈 줄도 값
  의 일부가 되도록 합니다. 동시에, 가독성을 높이기 위해 키를 임의로 들
  여 쓸 수 있습니다. 결과적으로, 구성 파일이 커지고 복잡해지면, 사용자
  가 파일 구조를 쉽게 놓칠 수 있습니다. 예를 들어 봅시다:

     [Section]
     key = multiline
       value with a gotcha

      this = is still a part of the multiline value of 'key'

  이것은 사용자가 가변 폭 글꼴을 사용하여 파일을 편집하고 있다면, 보는
  데 특히 문제가 될 수 있습니다. 따라서 응용 프로그램에 빈 줄이 있는
  값이 필요하지 않으면, 허용하지 않는 것이 좋습니다. 이렇게 하면 빈 줄
  이 매번 키를 분리합니다. 위의 예에서는, "key"와 "this"의 두 키를 생
  성합니다.

* *default_section*, 기본값: "configparser.DEFAULTSECT" (즉:
  ""DEFAULT"")

  다른 섹션이나 보간 목적으로 기본값의 특수한 섹션을 허용하는 규칙은
  이 라이브러리의 강력한 개념으로, 사용자가 복잡한 선언적 구성을 만들
  수 있도록 합니다. 이 섹션은 일반적으로 ""DEFAULT""라고 하지만 다른
  유효한 섹션 이름을 가리키도록 사용자 정의할 수 있습니다. 몇 가지 흔
  한 값은 이렇습니다: ""general""이나 ""common"". 제공된 이름은 모든
  소스에서 읽을 때 기본값 섹션을 인식하는 데 사용되며 구성을 파일에 다
  시 쓸 때 사용됩니다. 현재 값은 "parser_instance.default_section" 어
  트리뷰트를 사용하여 꺼낼 수 있으며 실행 시간에 수정될 수 있습니다 (
  즉 파일을 한 형식에서 다른 형식으로 변환하기 위해).

* *interpolation*, 기본값: "configparser.BasicInterpolation"

  *interpolation* 인자를 통해 사용자 정의 처리기를 제공하여 보간 동작
  을 사용자 정의할 수 있습니다. "None"은 보간을 완전히 끄는 데 사용할
  수 있으며, "ExtendedInterpolation()" 은 "zc.buildout"에서 영감을 얻
  은 고급 변형을 제공합니다. 이 주제에 관한 자세한 내용은 전용 설명서
  섹션에 있습니다. "RawConfigParser" 의 기본값은 "None"입니다.

* *converters*, 기본값: 설정되지 않음

  구성 구문 분석기는 형 변환을 수행하는 옵션값 게터를 제공합니다. 기본
  적으로 "getint()", "getfloat()" 및 "getboolean()"가 구현됩니다. 다른
  게터가 바람직하다면, 사용자는 그것들을 서브 클래스에 정의하거나 각
  키가 변환기의 이름이고 각 값이 이 변환을 구현하는 콜러블인 딕셔너리
  를 전달할 수 있습니다. 예를 들어, "{'decimal': decimal.Decimal}"을
  전달하면 구문 분석기 객체와 모든 섹션 프락시 모두에 "getdecimal()"이
  추가됩니다. 즉, "parser_instance.getdecimal('section', 'key',
  fallback=0)"과 "parser_instance['section'].getdecimal('key', 0)"을
  모두 쓸 수 있습니다.

  변환기가 구문 분석기의 상태에 액세스해야 하면, 구성 구문 분석기 서브
  클래스에서 메서드로 구현될 수 있습니다. 이 메서드의 이름이 "get"으로
  시작하면, 모든 섹션 프락시에서 dict 호환 형식으로 사용할 수 있습니다
  (위의 "getdecimal()" 예를 참조하십시오).

이러한 구문 분석기 어트리뷰트의 기본값을 재정의하여 더 고급 사용자 정
의를 수행할 수 있습니다. 기본값은 클래스에서 정의되므로, 서브 클래스나
어트리뷰트 대입으로 재정의할 수 있습니다.

ConfigParser.BOOLEAN_STATES

   "getboolean()"을 사용할 때 기본적으로, 구성 구문 분석기는 다음 값들
   을 "True"로 간주하고: "'1'", "'yes'", "'true'", "'on'" 다음 값들을
   "False"로 간주합니다: "'0'", "'no'", "'false'", "'off'". 문자열과
   불리언 결과를 사용자 정의 딕셔너리로 지정하여 이를 재정의할 수 있습
   니다. 예를 들면:

      >>> custom = configparser.ConfigParser()
      >>> custom['section1'] = {'funky': 'nope'}
      >>> custom['section1'].getboolean('funky')
      Traceback (most recent call last):
      ...
      ValueError: Not a boolean: nope
      >>> custom.BOOLEAN_STATES = {'sure': True, 'nope': False}
      >>> custom['section1'].getboolean('funky')
      False

   다른 일반적인 불리언 쌍에는 "accept"/"reject"나
   "enabled"/"disabled"가 포함됩니다.

ConfigParser.optionxform(option)

   이 메서드는 모든 읽기, get 또는 set 연산에서 옵션 이름을 변환합니다
   . 기본값은 이름을 소문자로 변환합니다. 이는 또한 구성 파일을 기록할
   때 모든 키가 소문자가 됨을 의미합니다. 이것이 부적절하다면 이 메서
   드를 재정의하십시오. 예를 들면:

      >>> config = """
      ... [Section1]
      ... Key = Value
      ...
      ... [Section2]
      ... AnotherKey = Value
      ... """
      >>> typical = configparser.ConfigParser()
      >>> typical.read_string(config)
      >>> list(typical['Section1'].keys())
      ['key']
      >>> list(typical['Section2'].keys())
      ['anotherkey']
      >>> custom = configparser.RawConfigParser()
      >>> custom.optionxform = lambda option: option
      >>> custom.read_string(config)
      >>> list(custom['Section1'].keys())
      ['Key']
      >>> list(custom['Section2'].keys())
      ['AnotherKey']

   참고:

     optionxform 함수는 옵션 이름을 규범적 형식으로 변환합니다. 이 함
     수는 멱등적(idempotent) 함수여야 합니다: 이름이 이미 규범적 형식
     이면, 변경되지 않은 상태로 반환해야 합니다.

ConfigParser.SECTCRE

   섹션 헤더를 구문 분석하는 데 사용되는 컴파일된 정규식. 기본값은
   "[section]"을 이름 ""section""과 일치시킵니다. 공백은 섹션 이름의
   일부로 간주해서, "[  larch  ]"는 이름이 ""  larch  ""인 섹션으로 읽
   힙니다. 이것이 부적절하다면 이 어트리뷰트를 재정의하십시오. 예를 들
   면:

      >>> import re
      >>> config = """
      ... [Section 1]
      ... option = value
      ...
      ... [  Section 2  ]
      ... another = val
      ... """
      >>> typical = configparser.ConfigParser()
      >>> typical.read_string(config)
      >>> typical.sections()
      ['Section 1', '  Section 2  ']
      >>> custom = configparser.ConfigParser()
      >>> custom.SECTCRE = re.compile(r"\[ *(?P<header>[^]]+?) *\]")
      >>> custom.read_string(config)
      >>> custom.sections()
      ['Section 1', 'Section 2']

   참고:

     ConfigParser 객체는 옵션 줄을 인식하기 위해 "OPTCRE" 어트리뷰트도
     사용하지만, 생성자 옵션 *allow_no_value*와 *delimiters*를 방해하
     기 때문에 재정의하지 않는 것이 좋습니다.


레거시 API 예제
===============

주로 이전 버전과의 호환성 문제로 인해, "configparser"는 명시적인
"get"/"set" 메서드로 레거시 API도 제공합니다. 아래에 설명된 메서드에
대한 유효한 사용 사례가 있지만, 새 프로젝트에는 매핑 프로토콜 액세스가
선호됩니다. 레거시 API는 때때로 더 고급이고, 저수준(low-level)이며 완
전히 반 직관적입니다.

구성 파일에 쓰는 예:

   import configparser

   config = configparser.RawConfigParser()

   # RawConfigParser 의 set 함수를 사용하면, 문자열이 아닌 값을
   # 키에 내부적으로 대입할 수 있지만, 파일에 쓰려고 할 때나
   # 비 원시 모드로 가져올 때 에러가 발생함에 유의하십시오.
   # 매핑 프로토콜이나 ConfigParser의 set()을 사용하여
   # 값을 설정하면 이러한 대입이 허용되지 않습니다.
   config.add_section('Section1')
   config.set('Section1', 'an_int', '15')
   config.set('Section1', 'a_bool', 'true')
   config.set('Section1', 'a_float', '3.1415')
   config.set('Section1', 'baz', 'fun')
   config.set('Section1', 'bar', 'Python')
   config.set('Section1', 'foo', '%(bar)s is %(baz)s!')

   # 구성 파일을 'example.cfg'에 기록하기
   with open('example.cfg', 'w') as configfile:
       config.write(configfile)

구성 파일을 다시 읽는 예:

   import configparser

   config = configparser.RawConfigParser()
   config.read('example.cfg')

   # 값이 float가 아니면 getfloat()는 예외를 발생시킵니다
   # getint()와 getboolean() 또한 해당 유형에 대해 이렇게 합니다
   a_float = config.getfloat('Section1', 'a_float')
   an_int = config.getint('Section1', 'an_int')
   print(a_float + an_int)

   # 다음 출력은 '%(bar)s' 나 '%(baz)s' 를 보간하지 않음에 유의하십시오.
   # RawConfigParser() 를 사용하고 있기 때문입니다.
   if config.getboolean('Section1', 'a_bool'):
       print(config.get('Section1', 'foo'))

보간을 얻으려면, "ConfigParser"를 사용하십시오:

   import configparser

   cfg = configparser.ConfigParser()
   cfg.read('example.cfg')

   # 단일 get 연산에서 보간을 사용하지 않으려면 get()의 선택적 *raw* 인자를
   # True로 설정하십시오.
   print(cfg.get('Section1', 'foo', raw=False))  # -> "Python is fun!"
   print(cfg.get('Section1', 'foo', raw=True))   # -> "%(bar)s is %(baz)s!"

   # 선택적 *vars* 인자는 보간에서 우선하는 멤버가
   # 포함된 dict입니다.
   print(cfg.get('Section1', 'foo', vars={'bar': 'Documentation',
                                          'baz': 'evil'}))

   # 선택적 *fallback* 인자를 사용하여 대체 값을 제공할 수 있습니다
   print(cfg.get('Section1', 'foo'))
         # -> "Python is fun!"

   print(cfg.get('Section1', 'foo', fallback='Monty is not.'))
         # -> "Python is fun!"

   print(cfg.get('Section1', 'monster', fallback='No such things as monsters.'))
         # -> "No such things as monsters."

   # print(cfg.get('Section1', 'monster')) 만은 NoOptionError 를 발생시킵니다
   # 하지만 이렇게 사용할 수도 있습니다:

   print(cfg.get('Section1', 'monster', fallback=None))
         # -> None

기본값은 두 가지 유형의 ConfigParser 모두에서 사용할 수 있습니다. 사용
된 옵션이 다른 곳에 정의되어 있지 않으면 보간에 사용됩니다.

   import configparser

   # 'bar'와 'baz'의 기본값이 각각 'Life'와 'hard'인 새 인스턴스
   config = configparser.ConfigParser({'bar': 'Life', 'baz': 'hard'})
   config.read('example.cfg')

   print(config.get('Section1', 'foo'))     # -> "Python is fun!"
   config.remove_option('Section1', 'bar')
   config.remove_option('Section1', 'baz')
   print(config.get('Section1', 'foo'))     # -> "Life is hard!"


ConfigParser 객체
=================

class configparser.ConfigParser(defaults=None, dict_type=dict, allow_no_value=False, *, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation(), converters={}, allow_unnamed_section=False)

   메인 구성 구문 분석기. *defaults*가 주어지면, 내장 기본값의 딕셔너
   리로 초기화됩니다. *dict_type*이 제공되면, 섹션 리스트, 섹션 내의
   옵션 및 기본값에 대한 딕셔너리 객체를 만드는 데 사용됩니다.

   *delimiters*가 주어지면, 키를 값과 나누는 부분 문자열 집합으로 사용
   됩니다. *comment_prefixes*가 주어지면, 주석이 없다면 빈 줄일 곳에서
   주석을 시작하는 접두사의 부분 문자열 집합으로 사용됩니다. 주석은 들
   여 쓸 수 있습니다. *inline_comment_prefixes*가 주어지면, 비어 있지
   않은 줄에서 주석을 시작하는 접두사의 부분 문자열 집합으로 사용됩니
   다.

   *strict*가 "True"(기본값)이면, 구문 분석기는 단일 소스(파일, 문자열
   또는 딕셔너리)에서 읽는 동안 섹션이나 옵션의 중복을 허용하지 않고,
   "DuplicateSectionError" 나 "DuplicateOptionError"를 발생시킵니다.
   *empty_lines_in_values*가 "False"이면 (기본값: "True"), 각 빈 줄은
   옵션의 끝을 나타냅니다. 그렇지 않으면, 여러 줄 옵션의 내부 빈 줄이
   값의 일부로 유지됩니다. *allow_no_value*가 "True"이면 (기본값:
   "False"), 값이 없는 옵션이 허용됩니다; 이들에 대해 저장되는 값은
   "None"이며 후행 구분자 없이 직렬화됩니다.

   *default_section*이 주어지면, 다른 섹션과 보간 목적의 기본값을 담는
   특수한 섹션의 이름을 지정합니다 (보통 ""DEFAULT""라는 이름). 이 값
   은 "default_section" 인스턴스 어트리뷰트를 사용하여 실행 시간에 꺼
   내고 변경할 수 있습니다. 이는 이미 구문 분석된 구성 파일을 재평가하
   지 않지만, 구문 분석된 설정을 새 구성 파일에 기록할 때 사용됩니다.

   *interpolation* 인자를 통해 사용자 정의 처리기를 제공하여 보간 동작
   을 사용자 정의할 수 있습니다. "None"은 보간을 완전히 끄는 데 사용할
   수 있으며, "ExtendedInterpolation()" 은 "zc.buildout"에서 영감을 얻
   은 고급 변형을 제공합니다. 이 주제에 관한 자세한 내용은 전용 설명서
   섹션에 있습니다.

   보간에 사용된 모든 옵션 이름은 다른 옵션 이름 참조와 마찬가지로
   "optionxform()" 메서드를 통해 전달됩니다. 예를 들어, (옵션 이름을
   소문자로 변환하는) "optionxform()"의 기본 구현을 사용하면, 값 "foo
   %(bar)s"와 "foo %(BAR)s"가 동등합니다.

   *converters*가 주어지면, 각 키는 형 변환기의 이름을 나타내고 각 값
   은 문자열에서 원하는 데이터형으로의 변환을 구현하는 콜러블인 딕셔너
   리이어야 합니다. 모든 변환기는 구문 분석기 객체와 섹션 프락시에서
   자신만의 해당 "get*()" 메서드를 갖습니다.

   When *allow_unnamed_section* is "True" (default: "False"), the
   first section name can be omitted. See the "Unnamed Sections"
   section.

   It is possible to read several configurations into a single
   "ConfigParser", where the most recently added configuration has the
   highest priority. Any conflicting keys are taken from the more
   recent configuration while the previously existing keys are
   retained. The example below reads in an "override.ini" file, which
   will override any conflicting keys from the "example.ini" file.

      [DEFAULT]
      ServerAliveInterval = -1

      >>> config_override = configparser.ConfigParser()
      >>> config_override['DEFAULT'] = {'ServerAliveInterval': '-1'}
      >>> with open('override.ini', 'w') as configfile:
      ...     config_override.write(configfile)
      ...
      >>> config_override = configparser.ConfigParser()
      >>> config_override.read(['example.ini', 'override.ini'])
      ['example.ini', 'override.ini']
      >>> print(config_override.get('DEFAULT', 'ServerAliveInterval'))
      -1

   버전 3.1에서 변경: 기본 *dict_type*은 "collections.OrderedDict"입니
   다.

   버전 3.2에서 변경: *allow_no_value*, *delimiters*,
   *comment_prefixes*, *strict*, *empty_lines_in_values*,
   *default_section* 및 *interpolation*이 추가되었습니다.

   버전 3.5에서 변경: *converters* 인자가 추가되었습니다.

   버전 3.7에서 변경: *defaults* 인자는 "read_dict()"로 읽혀, 구문 분
   석기 전체에 일관된 동작을 제공합니다: 문자열이 아닌 키와 값은 묵시
   적으로 문자열로 변환됩니다.

   버전 3.8에서 변경: 이제 삽입 순서를 유지하므로, 기본 *dict_type*은
   "dict"입니다.

   버전 3.13에서 변경: Raise a "MultilineContinuationError" when
   *allow_no_value* is "True", and a key without a value is continued
   with an indented line.

   버전 3.13에서 변경: *allow_unnamed_section* 인자가 추가되었습니다.

   defaults()

      인스턴스 전체 기본값을 포함하는 딕셔너리를 반환합니다.

   sections()

      사용 가능한 섹션 리스트를 반환합니다; *기본값 섹션*은 리스트에
      포함되지 않습니다.

   add_section(section)

      *section*이라는 섹션을 인스턴스에 추가합니다. 주어진 이름의 섹션
      이 이미 존재하면, "DuplicateSectionError" 가 발생합니다. *기본값
      섹션* 이름이 전달되면, "ValueError"가 발생합니다. 섹션의 이름은
      문자열이어야 합니다; 그렇지 않으면, "TypeError"가 발생합니다.

      버전 3.2에서 변경: 문자열이 아닌 섹션 이름은 "TypeError"를 발생
      시킵니다.

   has_section(section)

      이름 지정된 *section*이 구성에 있는지를 나타냅니다. *기본값 섹션
      *은 인정되지 않습니다.

   options(section)

      지정된 *section*에서 사용 가능한 옵션 리스트를 반환합니다.

   has_option(section, option)

      주어진 *section*이 존재하고, 주어진 *option*을 포함하면, "True"
      를 반환합니다; 그렇지 않으면 "False"를 반환합니다. 지정된
      *section*이 "None"이거나 빈 문자열이면, DEFAULT로 가정합니다.

   read(filenames, encoding=None)

      파일명들의 이터러블을 읽고 구문 분석하여, 성공적으로 구문 분석된
      파일명의 리스트를 반환합니다.

      *filenames*가 문자열, "bytes" 객체 또는 *경로류 객체*이면 단일
      파일명으로 처리됩니다. *filenames*에서 이름 지정된 파일을 열 수
      없으면, 해당 파일은 무시됩니다. 이는 잠재적인 구성 파일 위치(예
      를 들어, 현재 디렉터리, 사용자의 홈 디렉터리 및 일부 시스템 전체
      디렉터리)의 이터러블을 지정할 수 있도록 설계되었으며, 이터러블에
      있는 존재하는 모든 구성 파일을 읽습니다.

      제공된 이름의 파일이 아무것도 없으면, "ConfigParser" 인스턴스는
      빈 데이터 집합을 포함합니다. 파일에서 초깃값을 로드해야 하는 응
      용 프로그램은 선택적 파일에 대해 "read()"를 호출하기 전에
      "read_file()"을 사용하여 필수 파일을 로드해야 합니다:

         import configparser, os

         config = configparser.ConfigParser()
         config.read_file(open('defaults.cfg'))
         config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')],
                     encoding='cp1250')

      버전 3.2에서 변경: *encoding* 매개 변수를 추가했습니다. 이전에는
      , "open()"의 기본 인코딩을 사용하여 모든 파일을 읽었습니다.

      버전 3.6.1에서 변경: *filenames* 매개 변수는 *경로류 객체*를 받
      아들입니다.

      버전 3.7에서 변경: *filenames* 매개 변수는 "bytes" 객체를 받아들
      입니다.

   read_file(f, source=None)

      *f*에서 구성 데이터를 읽고 구문 분석합니다. *f*는 유니코드 문자
      열을 산출하는 이터러블 이어야 합니다 (예를 들어 텍스트 모드로 열
      린 파일).

      선택적 인자 *source*는 읽을 파일의 이름을 지정합니다. 지정하지
      않고 *f*에 "name" 어트리뷰트가 있으면, 이것이 *source*로 사용됩
      니다; 기본값은 "'<???>'"입니다.

      Added in version 3.2: "readfp()"를 대체합니다.

   read_string(string, source='<string>')

      문자열에서 구성 데이터를 구문 분석합니다.

      선택적 인자 *source*는 전달된 string의 문맥 특정 이름을 지정합니
      다. 지정하지 않으면, "'<string>'"이 사용됩니다. 일반적으로 파일
      시스템 경로나 URL이어야 합니다.

      Added in version 3.2.

   read_dict(dictionary, source='<dict>')

      딕셔너리와 같은 "items()" 메서드를 제공하는 임의의 객체에서 구성
      을 로드합니다. 키는 섹션 이름이며, 값은 섹션에 있어야 하는 키와
      값이 들어 있는 딕셔너리입니다. 사용된 딕셔너리 형이 순서를 유지
      하면, 섹션과 해당 키가 순서대로 추가됩니다. 값은 자동으로 문자열
      로 변환됩니다.

      선택적 인자 *source*는 전달된 dictionary의 문맥 특정 이름을 지정
      합니다. 지정하지 않으면, "<dict>"가 사용됩니다.

      이 메서드를 사용하면 구문 분석 기간에 상태를 복사할 수 있습니다.

      Added in version 3.2.

   get(section, option, *, raw=False, vars=None[, fallback])

      명명된 *section*에서 *option* 값을 가져옵니다. *vars*가 제공되면
      , 딕셔너리이어야 합니다. *option*은 *vars* (제공되면), *section*
      및 *DEFAULTSECT* 에서 순서대로 조회됩니다. 키를 찾을 수 없고
      *fallback*이 제공되면, 대체 값으로 사용됩니다. "None"은
      *fallback* 값으로 제공될 수 있습니다.

      *raw* 인자가 참이 아닌 한, 모든 "'%'" 보간이 반환 값에서 확장됩
      니다. 보간 키의 값은 옵션과 같은 방식으로 조회됩니다.

      버전 3.2에서 변경: 인자 *raw*, *vars* 및 *fallback*은 사용자가
      세 번째 인자를 *fallback* 폴 백으로 사용하지 못하도록 하기 위해
      키워드 전용입니다 (특히 매핑 프로토콜을 사용할 때).

   getint(section, option, *, raw=False, vars=None[, fallback])

      지정된 *section*의 *option*을 정수로 강제 변환하는 편의 메서드.
      *raw*, *vars* 및 *fallback*에 대한 설명은 "get()"을 참조하십시오
      .

   getfloat(section, option, *, raw=False, vars=None[, fallback])

      지정된 *section*의 *option*을 부동 소수점 수로 강제 변환하는 편
      의 메서드. *raw*, *vars* 및 *fallback*에 대한 설명은 "get()"을
      참조하십시오.

   getboolean(section, option, *, raw=False, vars=None[, fallback])

      지정된 *section*의 *option*을 불리언 값으로 강제 변환하는 편의
      메서드. 옵션에 허용되는 값은 이 메서드가 "True"를 반환하게 하는
      "'1'", "'yes'", "'true'" 및 "'on'"과 "False"를 반환하게 하는
      "'0'", "'no'", "'false'" 및 "'off'"입니다. 이 문자열 값은 대소
      문자를 구분하지 않고 확인됩니다. 다른 모든 값은 "ValueError"를
      발생시킵니다. *raw*, *vars* 및 *fallback*에 대한 설명은 "get()"
      을 참조하십시오.

   items(raw=False, vars=None)
   items(section, raw=False, vars=None)

      *section*이 제공되지 않으면, DEFAULTSECT를 포함하여,
      *section_name*, *section_proxy* 쌍의 리스트를 반환합니다.

      그렇지 않으면, 주어진 *section*의 옵션에 대해 *name*, *value* 쌍
      의 리스트를 반환합니다. 선택적 인자는 "get()" 메서드에서와 같은
      의미입니다.

      버전 3.8에서 변경: *vars*에 있는 항목은 더는 결과에 나타나지 않
      습니다. 이전 동작은 실제 구문 분석기 옵션과 보간을 위해 제공된
      변수를 혼합했습니다.

   set(section, option, value)

      주어진 섹션이 존재하면, 주어진 옵션을 지정된 값으로 설정합니다;
      그렇지 않으면 "NoSectionError"를 발생시킵니다. *option*과
      *value*는 문자열이어야 합니다; 그렇지 않으면, "TypeError"가 발생
      합니다.

   write(fileobject, space_around_delimiters=True)

      텍스트 모드로 열렸어야 하는 (문자열을 받아들이는), 지정된 *파일
      객체*에 구성의 표현을 기록합니다. 이 표현은 향후 "read()" 호출로
      구문 분석할 수 있습니다. *space_around_delimiters*가 참이면, 키
      와 값 사이의 구분자는 공백으로 둘러싸입니다.

   참고:

     Comments in the original configuration file are not preserved
     when writing the configuration back. What is considered a
     comment, depends on the given values for *comment_prefix* and
     *inline_comment_prefix*.

   remove_option(section, option)

      지정된 *section*에서 지정된 *option*을 제거합니다. 섹션이 존재하
      지 않으면, "NoSectionError"를 발생시킵니다. 제거되는 옵션이 존재
      했으면 "True"를 반환합니다; 그렇지 않으면 "False"를 반환합니다.

   remove_section(section)

      지정된 *section*을 구성에서 제거합니다. 실제로 섹션이 존재하면,
      "True"를 반환합니다. 그렇지 않으면 "False"를 반환합니다.

   optionxform(option)

      입력 파일에서 발견되거나 클라이언트 코드에서 전달된 옵션 이름
      *option*을 내부 구조에서 사용되어야 하는 형식으로 변환합니다. 기
      본 구현은 *option*의 소문자 버전을 반환합니다; 이 동작에 영향을
      주기 위해 서브 클래스가 이것을 재정의하거나 클라이언트 코드가 인
      스턴스에 이 이름의 어트리뷰트를 설정할 수 있습니다.

      이 메서드를 사용하기 위해 구문 분석기를 서브 클래싱할 필요는 없
      으며, 문자열 인자를 취해서 문자열을 반환하는 함수로 인스턴스에
      설정할 수도 있습니다. 예를 들어 "str"로 설정하면 옵션 이름이 대
      소 문자를 구분하게 됩니다:

         cfgparser = ConfigParser()
         cfgparser.optionxform = str

      구성 파일을 읽을 때, "optionxform()"이 호출되기 전에 옵션 이름
      주위의 공백이 제거됨에 유의하십시오.

configparser.UNNAMED_SECTION

   A special object representing a section name used to reference the
   unnamed section (see Unnamed Sections).

configparser.MAX_INTERPOLATION_DEPTH

   *raw* 매개 변수가 거짓일 때 "get()"의 재귀 보간의 최대 깊이. 기본
   *interpolation*을 사용할 때만 의미 있습니다.


RawConfigParser 객체
====================

class configparser.RawConfigParser(defaults=None, dict_type=dict, allow_no_value=False, *, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation(), converters={}, allow_unnamed_section=False)

   "ConfigParser"의 레거시 변형. 기본적으로 보간이 비활성화되어 있으며
   레거시 "defaults=" 키워드 인자 처리뿐만 아니라 안전하지 않은
   "add_section"과 "set" 메서드를 통해 문자열이 아닌 섹션 이름, 옵션
   이름 및 값을 허용합니다.

   버전 3.2에서 변경: *allow_no_value*, *delimiters*,
   *comment_prefixes*, *strict*, *empty_lines_in_values*,
   *default_section* 및 *interpolation*이 추가되었습니다.

   버전 3.5에서 변경: *converters* 인자가 추가되었습니다.

   버전 3.8에서 변경: 이제 삽입 순서를 유지하므로, 기본 *dict_type*은
   "dict"입니다.

   버전 3.13에서 변경: *allow_unnamed_section* 인자가 추가되었습니다.

   참고:

     내부에 저장되는 값의 형을 검사하는 "ConfigParser"를 대신 사용하는
     것을 고려하십시오. 보간을 원하지 않으면,
     "ConfigParser(interpolation=None)" 을 사용할 수 있습니다.

   add_section(section)

      *section*이라는 이름의 섹션을 인스턴스에 추가합니다. 주어진 이름
      의 섹션이 이미 존재하면, "DuplicateSectionError" 가 발생합니다.
      *기본값 섹션* 이름이 전달되면, "ValueError"가 발생합니다.

      *section*의 형을 검사하지 않아서 사용자가 문자열이 아닌 섹션을
      만들 수 있도록 합니다. 이 동작은 지원되지 않으며 내부 에러를 일
      으킬 수 있습니다.

   set(section, option, value)

      주어진 섹션이 존재하면, 주어진 옵션을 지정된 값으로 설정합니다;
      그렇지 않으면 "NoSectionError"를 발생시킵니다. 문자열이 아닌 값
      을 *내부에* 저장하도록 "RawConfigParser"(또는 *raw* 매개 변수가
      참으로 설정된 "ConfigParser")를 사용할 수 있지만, 전체 기능(보간
      과 파일로의 출력을 포함하는)은 문자열 값으로만 수행할 수 있습니
      다.

      이 메서드를 사용하면 문자열이 아닌 값을 키에 내부적으로 대입할
      수 있습니다. 이 동작은 지원되지 않으며 파일에 쓰려고 하거나 비
      원시 모드에서 가져오려고 할 때 에러가 발생합니다. 이러한 대입을
      허용하지 않는 **매핑 프로토콜 API를 사용하십시오**.


예외
====

exception configparser.Error

   다른 모든 "configparser" 예외의 베이스 클래스.

exception configparser.NoSectionError

   지정된 섹션을 찾지 못할 때 발생하는 예외.

exception configparser.DuplicateSectionError

   이미 존재하는 이름으로 "add_section()"을 호출하거나 엄격한(strict)
   구문 분석기에서 단일 입력 파일, 문자열 또는 딕셔너리에서 섹션이 두
   번 이상 발견될 때 발생하는 예외.

   버전 3.2에서 변경: 선택적 *source*와 *lineno* 어트리뷰트 및
   "__init__()"에 대한 인자를 추가했습니다.

exception configparser.DuplicateOptionError

   단일 파일, 문자열 또는 딕셔너리에서 읽는 동안 단일 옵션이 두 번 나
   타날 때 엄격한(strict) 구문 분석기가 발생시키는 예외. 이는 맞춤법과
   대소 문자 구분과 관련된 에러를 잡습니다, 예를 들어 딕셔너리에는 대
   소 문자를 구분하지 않는 같은 구성 키를 나타내는 두 개의 키가 있을
   수 있습니다.

exception configparser.NoOptionError

   지정된 섹션에서 지정된 옵션을 찾지 못할 때 발생하는 예외.

exception configparser.InterpolationError

   문자열 보간 수행 시 문제가 발생할 때 발생하는 예외의 베이스 클래스.

exception configparser.InterpolationDepthError

   이터레이션 횟수가 "MAX_INTERPOLATION_DEPTH"를 초과하여 문자열 보간
   을 완료할 수 없을 때 발생하는 예외. "InterpolationError"의 서브 클
   래스.

exception configparser.InterpolationMissingOptionError

   값에서 참조된 옵션이 존재하지 않을 때 발생하는 예외.
   "InterpolationError"의 서브 클래스.

exception configparser.InterpolationSyntaxError

   치환이 이루어질 소스 텍스트가 요구되는 문법을 준수하지 않을 때 발생
   하는 예외. "InterpolationError"의 서브 클래스.

exception configparser.MissingSectionHeaderError

   섹션 헤더가 없는 파일을 구문 분석하려고 할 때 발생하는 예외.

exception configparser.ParsingError

   파일 구문 분석 중에 에러가 발생할 때 발생하는 예외.

   버전 3.12에서 변경: 일관성을 위해 "filename" 어트리뷰트와
   "__init__()" 생성자 인자가 제거되었습니다. 3.2부터 "source"라는 이
   름으로 사용할 수 있었습니다.

exception configparser.MultilineContinuationError

   Exception raised when a key without a corresponding value is
   continued with an indented line.

   Added in version 3.13.

-[ 각주 ]-

[1] 구성 구문 분석기는 심도 있는 사용자 정의를 허용합니다. 각주 참조로
    요약된 동작을 변경하는 데 관심이 있으면 구문 분석기 동작 사용자 정
    의 섹션을 참조하십시오.
