# 파이썬 초기화 구성

버전 3.8에 추가.

구조체:

- `PyConfig`

- `PyPreConfig`

- `PyStatus`

- `PyWideStringList`

함수:

- `PyConfig_Clear()`

- `PyConfig_InitIsolatedConfig()`

- `PyConfig_InitPythonConfig()`

- `PyConfig_Read()`

- `PyConfig_SetArgv()`

- `PyConfig_SetBytesArgv()`

- `PyConfig_SetBytesString()`

- `PyConfig_SetString()`

- `PyConfig_SetWideStringList()`

- `PyPreConfig_InitIsolatedConfig()`

- `PyPreConfig_InitPythonConfig()`

- `PyStatus_Error()`

- `PyStatus_Exception()`

- `PyStatus_Exit()`

- `PyStatus_IsError()`

- `PyStatus_IsExit()`

- `PyStatus_NoMemory()`

- `PyStatus_Ok()`

- `PyWideStringList_Append()`

- `PyWideStringList_Insert()`

- `Py_ExitStatusException()`

- `Py_InitializeFromConfig()`

- `Py_PreInitialize()`

- `Py_PreInitializeFromArgs()`

- `Py_PreInitializeFromBytesArgs()`

- `Py_RunMain()`

- `Py_GetArgcArgv()`

사전 구성(`PyPreConfig` 형)은 `_PyRuntime.preconfig`에 저장되고 구성(`PyConfig` 형)은 `PyInterpreterState.config`에 저장됩니다.

초기화, 파이널리제이션 및 스레드도 참조하십시오.

더 보기

PEP 587 “파이썬 초기화 구성”.

## PyWideStringList

`PyWideStringList`

  `wchar_t*` 문자열의 리스트.

  length가 0이 아니면, items는 `NULL`이 아니어야 하고 모든 문자열은 `NULL`이 아니어야 합니다.

  메서드:

  PyStatus `PyWideStringList_Append`( PyWideStringList *list, const wchar_t *item)

    item을 list에 추가합니다.

    이 함수를 호출하려면 파이썬을 사전 초기화해야 합니다.

  PyStatus `PyWideStringList_Insert`( PyWideStringList *list, Py_ssize_t index, const wchar_t *item)

    item을 list의 index에 삽입합니다.

    index가 list 길이보다 크거나 같으면, item을 list에 추가(append)합니다.

    index는 0보다 크거나 같아야 합니다.

    이 함수를 호출하려면 파이썬을 사전 초기화해야 합니다.

  구조체 필드:

  Py_ssize_t `length`

    리스트 길이.

  wchar_t** `items`

    리스트 항목들.

## PyStatus

`PyStatus`

  초기화 함수 상태를 저장하는 구조체: 성공, 에러 또는 종료.

  에러의 경우, 에러를 만든 C 함수 이름을 저장할 수 있습니다.

  구조체 필드:

  int `exitcode`

    종료 코드. `exit()`에 전달된 인자.

  const char *`err_msg`

    에러 메시지.

  const char *`func`

    에러를 만든 함수의 이름, `NULL`일 수 있습니다.

  상태를 만드는 함수:

  PyStatus `PyStatus_Ok`(void)

    성공.

  PyStatus `PyStatus_Error`(const char *err_msg)

    메시지가 포함된 초기화 에러.

  PyStatus `PyStatus_NoMemory`(void)

    메모리 할당 실패 (메모리 부족).

  PyStatus `PyStatus_Exit`(int exitcode)

    지정된 종료 코드로 파이썬을 종료합니다.

  상태를 처리하는 함수:

  int `PyStatus_Exception`( PyStatus status)

    상태가 에러입니까? 아니면 종료입니까? 참이면, 예외를 처리해야 합니다; 예를 들어 `Py_ExitStatusException()` 을 호출하여.

  int `PyStatus_IsError`( PyStatus status)

    결과가 에러입니까?

  int `PyStatus_IsExit`( PyStatus status)

    결과가 종료입니까?

  void `Py_ExitStatusException`( PyStatus status)

    status가 종료이면 `exit(exitcode)`를 호출합니다. status가 에러이면 에러 메시지를 인쇄하고 0이 아닌 종료 코드로 종료합니다. `PyStatus_Exception(status)`가 0이 아닐 때만 호출해야 합니다.

참고

내부적으로, 파이썬은 `PyStatus.func`를 설정하는 데는 매크로를 사용하는 반면, `func`가 `NULL`로 설정된 상태를 만드는 데는 함수를 사용합니다.

예:

    PyStatus alloc(void **ptr, size_t size)
    {
        *ptr = PyMem_RawMalloc(size);
        if (*ptr == NULL) {
            return PyStatus_NoMemory();
        }
        return PyStatus_Ok();
    }

    int main(int argc, char **argv)
    {
        void *ptr;
        PyStatus status = alloc(&ptr, 16);
        if (PyStatus_Exception(status)) {
            Py_ExitStatusException(status);
        }
        PyMem_Free(ptr);
        return 0;
    }

## PyPreConfig

`PyPreConfig`

  파이썬을 사전 초기화하는 데 사용되는 구조체:

  - 파이썬 메모리 할당자를 설정합니다

  - LC_CTYPE 로케일을 구성합니다

  - UTF-8 모드를 설정합니다

  사전 구성을 초기화하는 함수:

  void `PyPreConfig_InitPythonConfig`( PyPreConfig *preconfig)

    파이썬 구성으로 사전 구성을 초기화합니다.

  void `PyPreConfig_InitIsolatedConfig`( PyPreConfig *preconfig)

    격리된 구성으로 사전 구성을 초기화합니다.

  구조체 필드:

  int `allocator`

    메모리 할당자의 이름:

    - `PYMEM_ALLOCATOR_NOT_SET` (`0`): 메모리 할당자를 변경하지 않습니다 (기본값을 사용합니다)

    - `PYMEM_ALLOCATOR_DEFAULT` (`1`): 기본 메모리 할당자

    - `PYMEM_ALLOCATOR_DEBUG` (`2`): 디버그 훅이 있는 기본 메모리 할당자

    - `PYMEM_ALLOCATOR_MALLOC` (`3`): `malloc()`의 사용을 강제합니다

    - `PYMEM_ALLOCATOR_MALLOC_DEBUG` (`4`): 디버그 훅이 있는 `malloc()`의 사용을 강제합니다

    - `PYMEM_ALLOCATOR_PYMALLOC` (`5`): 파이썬 pymalloc 메모리 할당자

    - `PYMEM_ALLOCATOR_PYMALLOC_DEBUG` (`6`): 디버그 훅이 있는 파이썬 pymalloc 메모리 할당자

    파이썬이 `--without-pymalloc`을 사용하여 구성되면 `PYMEM_ALLOCATOR_PYMALLOC`과 `PYMEM_ALLOCATOR_PYMALLOC_DEBUG`은 지원되지 않습니다

    메모리 관리를 참조하십시오.

  int `configure_locale`

    LC_CTYPE 로케일을 사용자 선호 로케일로 설정합니까?? 0과 같으면, `coerce_c_locale`과 `coerce_c_locale_warn`을 0으로 설정합니다.

  int `coerce_c_locale`

    2와 같으면, C 로케일을 강제합니다; 1과 같으면, LC_CTYPE 로케일을 읽고 강제할지 결정합니다.

  int `coerce_c_locale_warn`

    0이 아니면, C 로케일이 강제될 때 경고가 발생합니다.

  int `dev_mode`

    `PyConfig.dev_mode`를 참조하십시오.

  int `isolated`

    `PyConfig.isolated`를 참조하십시오.

  int `legacy_windows_fs_encoding`(Windows only)

    0이 아니면, UTF-8 모드를 비활성화하고, 파이썬 파일 시스템 인코딩을 `mbcs`로 설정하고, 파일 시스템 에러 처리기를 `replace`로 설정합니다.

    윈도우에서만 사용 가능합니다. `#ifdef MS_WINDOWS` 매크로는 윈도우 특정 코드에 사용할 수 있습니다.

  int `parse_argv`

    0이 아니면, `Py_PreInitializeFromArgs()`와 `Py_PreInitializeFromBytesArgs()`는 일반 파이썬이 명령 줄 인자를 구문 분석하는 것과 같은 방식으로 `argv` 인자를 구문 분석합니다. 명령 줄 인자를 참조하십시오.

  int `use_environment`

    `PyConfig.use_environment`를 참조하십시오.

  int `utf8_mode`

    0이 아니면, UTF-8 모드를 활성화합니다.

## PyPreConfig를 사용한 사전 초기화

파이썬을 사전 초기화하는 함수:

PyStatus `Py_PreInitialize`(const PyPreConfig *preconfig)

  preconfig 사전 구성에서 파이썬을 사전 초기화합니다.

PyStatus `Py_PreInitializeFromBytesArgs`(const PyPreConfig *preconfig, int argc, char * const *argv)

  preconfig 사전 구성과 명령 줄 인자(바이트 문자열)에서 파이썬을 사전 초기화합니다.

PyStatus `Py_PreInitializeFromArgs`(const PyPreConfig *preconfig, int argc, wchar_t * const * argv)

  preconfig 사전 구성과 명령 줄 인자(와이드 문자열)에서 파이썬을 사전 초기화합니다.

호출자는 `PyStatus_Exception()`과 `Py_ExitStatusException()` 을 사용하여 예외(에러나 종료)를 처리해야 합니다.

파이썬 구성(`PyPreConfig_InitPythonConfig()`)의 경우, 명령 줄 인자로 파이썬을 초기화하면, 인코딩과 같은 사전 구성에 영향을 주기 때문에, 파이썬을 사전 구성하기 위해 명령 줄 인자도 전달되어야 합니다. 예를 들어, `-X utf8` 명령 줄 옵션은 UTF-8 모드를 활성화합니다.

`PyMem_SetAllocator()`는 `Py_PreInitialize()` 이후에 `Py_InitializeFromConfig()` 이전에 호출하여 사용자 정의 메모리 할당자를 설치할 수 있습니다. `PyPreConfig.allocator`가 `PYMEM_ALLOCATOR_NOT_SET`으로 설정되면 `Py_PreInitialize()` 전에 호출할 수 있습니다.

`PyMem_RawMalloc()`과 같은 파이썬 메모리 할당 함수는 파이썬 사전 초기화 전에 사용해서는 안 되지만, `malloc()`과 `free()`를 직접 호출하는 것은 항상 안전합니다. 사전 초기화 전에 `Py_DecodeLocale()`을 호출하면 안 됩니다.

UTF-8 모드를 활성화하기 위해 사전 초기화를 사용하는 예:

    PyStatus status;
    PyPreConfig preconfig;
    PyPreConfig_InitPythonConfig(&preconfig);

    preconfig.utf8_mode = 1;

    status = Py_PreInitialize(&preconfig);
    if (PyStatus_Exception(status)) {
        Py_ExitStatusException(status);
    }

    /* at this point, Python will speak UTF-8 */

    Py_Initialize();
    /* ... use Python API here ... */
    Py_Finalize();

## PyConfig

`PyConfig`

  파이썬을 구성하기 위한 대부분의 파라미터를 포함하는 구조체.

  구조체 메서드:

  void `PyConfig_InitPythonConfig`( PyConfig *config)

    파이썬 구성으로 구성을 초기화합니다.

  void `PyConfig_InitIsolatedConfig`( PyConfig *config)

    격리된 구성으로 구성을 초기화합니다.

  PyStatus `PyConfig_SetString`( PyConfig *config, wchar_t * const *config_str, const wchar_t *str)

    와이드 문자열 str을 `*config_str`로 복사합니다.

    필요하면 파이썬을 사전 초기화합니다.

  PyStatus `PyConfig_SetBytesString`( PyConfig *config, wchar_t * const *config_str, const char *str)

    `Py_DecodeLocale()`을 사용하여 str을 디코딩하고 결과를 `*config_str`에 설정합니다.

    필요하면 파이썬을 사전 초기화합니다.

  PyStatus `PyConfig_SetArgv`( PyConfig *config, int argc, wchar_t * const *argv)

    와이드 문자열로 명령 줄 인자를 설정합니다.

    필요하면 파이썬을 사전 초기화합니다.

  PyStatus `PyConfig_SetBytesArgv`( PyConfig *config, int argc, char * const *argv)

    명령 줄 인자를 설정합니다: `Py_DecodeLocale()`를 사용하여 바이트열을 디코딩합니다.

    필요하면 파이썬을 사전 초기화합니다.

  PyStatus `PyConfig_SetWideStringList`( PyConfig *config, PyWideStringList *list, Py_ssize_t length, wchar_t **items)

    와이드 문자열 리스트 list를 length와 items로 설정합니다.

    필요하면 파이썬을 사전 초기화합니다.

  PyStatus `PyConfig_Read`( PyConfig *config)

    모든 파이썬 구성을 읽습니다.

    이미 초기화된 필드는 변경되지 않습니다.

    필요하면 파이썬을 사전 초기화합니다.

  void `PyConfig_Clear`( PyConfig *config)

    구성 메모리를 해제합니다.

  대부분의 `PyConfig` 메서드는 필요하면 파이썬을 사전 초기화합니다. 이 경우, `PyConfig`를 기반으로 하는 파이썬 사전 초기화 구성입니다. `PyPreConfig`와 공통인 구성 필드가 조정되면, `PyConfig` 메서드를 호출하기 전에 설정해야 합니다:

  - `dev_mode`

  - `isolated`

  - `parse_argv`

  - `use_environment`

  또한, `PyConfig_SetArgv()`나 `PyConfig_SetBytesArgv()`가 사용되면, 사전 초기화 구성이 명령 줄 인자 (`parse_argv`가 0이 아니면)에 의존하기 때문에 다른 메서드보다 먼저 이 메서드를 호출해야 합니다.

  이 메서드의 호출자는 `PyStatus_Exception()`과 `Py_ExitStatusException()` 을 사용하여 예외(에러나 종료)를 처리해야 합니다.

  구조체 필드:

  PyWideStringList `argv`

    명령 줄 인자, `sys.argv`. 일반 파이썬이 파이썬 명령 줄 인자를 구문 분석하는 것과 같은 방식으로 `argv`를 구문 분석하려면 `parse_argv`를 참조하십시오. `argv`가 비어 있으면, 빈 문자열이 추가되어 `sys.argv`가 항상 존재하고 절대로 비어 있지 않도록 합니다.

  wchar_t* `base_exec_prefix`

    `sys.base_exec_prefix`.

  wchar_t* `base_executable`

    `sys._base_executable`: `__PYVENV_LAUNCHER__` 환경 변숫값, 또는 `PyConfig.executable`의 사본.

  wchar_t* `base_prefix`

    `sys.base_prefix`.

  wchar_t* `platlibdir`

    `sys.platlibdir`: 플랫폼 라이브러리 디렉터리 이름, `--with-platlibdir`로 구성 시간에 설정됩니다, `PYTHONPLATLIBDIR` 환경 변수로 재정의할 수 있습니다.

    버전 3.9에 추가.

  int `buffered_stdio`

    0과 같으면, 버퍼링 되지 않는 모드를 활성화하여, stdout과 stderr 스트림을 버퍼링하지 않도록 합니다.

    stdin은 항상 버퍼링 모드로 열립니다.

  int `bytes_warning`

    1과 같으면, `bytes`나 `bytearray`를 `str`와 비교하거나, 또는 `bytes`를 `int`와 비교할 때 경고를 발행합니다. 2 이상이면, `BytesWarning` 예외를 발생시킵니다.

  wchar_t* `check_hash_pycs_mode`

    해시 기반 `.pyc` 파일의 유효성 검증 동작을 제어합니다 ( PEP 552를 참조하십시오): `--check-hash-based-pycs` 명령 줄 옵션 값.

    유효한 값: `always`, `never` 및 `default`.

    기본값은 `default`입니다.

  int `configure_c_stdio`

    0이 아니면, C 표준 스트림(`stdio`, `stdout`, `stdout`)을 구성합니다. 예를 들어, 윈도우에서 해당 모드를 `O_BINARY`로 설정합니다.

  int `dev_mode`

    0이 아니면, 파이썬 개발 모드를 활성화합니다.

  int `dump_refs`

    0이 아니면, 종료 시 여전히 활성 상태인 모든 객체를 덤프합니다.

    `Py_TRACE_REFS` 매크로가 빌드에서 정의되어야 합니다.

  wchar_t* `exec_prefix`

    `sys.exec_prefix`.

  wchar_t* `executable`

    `sys.executable`.

  int `faulthandler`

    0이 아니면, 시작 시 `faulthandler.enable()`을 호출합니다.

  wchar_t* `filesystem_encoding`

    파일 시스템 인코딩, `sys.getfilesystemencoding()`.

  wchar_t* `filesystem_errors`

    파일 시스템 인코딩 에러, `sys.getfilesystemencodeerrors()`.

  unsigned long `hash_seed`
  int `use_hash_seed`

    무작위 해시 함수 시드.

    `use_hash_seed`가 0이면, 파이썬 시작 시 시드가 무작위로 선택되고, `hash_seed`는 무시됩니다.

  wchar_t* `home`

    파이썬 홈 디렉터리.

    기본적으로 `PYTHONHOME` 환경 변숫값에서 초기화됩니다.

  int `import_time`

    0이 아니면, 임포트 시간을 프로파일 합니다.

  int `inspect`

    스크립트나 명령을 실행한 후 대화식 모드로 들어갑니다.

  int `install_signal_handlers`

    시그널 처리기를 설치합니까?

  int `interactive`

    대화식 모드.

  int `isolated`

    0보다 크면, 격리 모드를 활성화합니다:

    - `sys.path`에는 스크립트 디렉터리(`argv[0]`이나 현재 디렉터리에서 계산됩니다)도 사용자의 site-packages 디렉터리도 없습니다.

    - 파이썬 REPL은 대화식 프롬프트에서 `readline`을 임포트 하지도 기본 readline 구성을 활성화하지도 않습니다.

    - `use_environment`와 `user_site_directory`를 0으로 설정합니다.

  int `legacy_windows_stdio`

    0이 아니면, `sys.stdin`, `sys.stdout` 및 `sys.stderr`에 `io.WindowsConsoleIO` 대신 `io.FileIO`를 사용합니다.

    윈도우에서만 사용 가능합니다. `#ifdef MS_WINDOWS` 매크로는 윈도우 특정 코드에 사용할 수 있습니다.

  int `malloc_stats`

    0이 아니면, 종료 시 파이썬 pymalloc 메모리 할당자에 대한 통계를 덤프합니다.

    파이썬이 `--without-pymalloc`을 사용하여 빌드되면 이 옵션은 무시됩니다.

  wchar_t* `pythonpath_env`

    `DELIM`(`os.path.pathsep`)으로 구분된 문자열로 표현된 모듈 검색 경로.

    기본적으로 `PYTHONPATH` 환경 변숫값에서 초기화됩니다.

  PyWideStringList `module_search_paths`
  int `module_search_paths_set`

    `sys.path`. `module_search_paths_set`이 0과 같으면, 경로 구성을 계산하는 함수가 `module_search_paths`를 재정의합니다.

  int `optimization_level`

    컴파일 최적화 수준:

    - 0: 틈 구멍 최적화기(Peephole optimizer) (그리고 `__debug__`이 `True`로 설정됩니다)

    - 1: 어서션을 제거합니다, `__debug__`을 `False`로 설정합니다

    - 2: 독스트링을 제거합니다

  int `parse_argv`

    0이 아니면, 일반 파이썬 명령 줄 인자와 같은 방식으로 `argv`를 구문 분석하고, `argv`에서 파이썬 인자를 제거합니다: 명령 줄 인자를 참조하십시오.

  int `parser_debug`

    0이 아니면, 구문 분석기 디버깅 출력을 켭니다 (컴파일 옵션에 따라, 전문가용입니다).

  int `pathconfig_warnings`

    0과 같으면, 경로 구성을 계산할 때 경고를 억제합니다 (유닉스 전용, 윈도우는 아무런 경고도 로그 하지 않습니다). 그렇지 않으면, 경고가 `stderr`에 기록됩니다.

  wchar_t* `prefix`

    `sys.prefix`.

  wchar_t* `program_name`

    프로그램 이름. `executable`을 초기화하는 데 사용되며, 초기 에러 메시지에서도 사용됩니다.

  wchar_t* `pycache_prefix`

    `sys.pycache_prefix`: `.pyc` 캐시 접두사.

    `NULL`이면, `sys.pycache_prefix`는 `None`으로 설정됩니다.

  int `quiet`

    침묵 모드. 예를 들어, 대화식 모드에서 저작권과 버전 메시지를 표시하지 않습니다.

  wchar_t* `run_command`

    `python3 -c COMMAND` 인자. `Py_RunMain()`에서 사용합니다.

  wchar_t* `run_filename`

    `python3 FILENAME` 인자. `Py_RunMain()`에서 사용합니다.

  wchar_t* `run_module`

    `python3 -m MODULE` 인자. `Py_RunMain()`에서 사용합니다.

  int `show_ref_count`

    종료 시 총 참조 횟수를 표시합니까?

    `-X showrefcount` 명령 줄 옵션으로 1로 설정됩니다.

    파이썬의 디버그 빌드가 필요합니다 (`Py_REF_DEBUG` 매크로를 정의해야 합니다).

  int `site_import`

    시작할 때 `site` 모듈을 임포트 합니까?

  int `skip_source_first_line`

    소스의 첫 줄을 건너뜁니까?

  wchar_t* `stdio_encoding`
  wchar_t* `stdio_errors`

    `sys.stdin`, `sys.stdout` 및 `sys.stderr`의 인코딩과 인코딩 에러.

  int `tracemalloc`

    0이 아니면, 시작 시 `tracemalloc.start()`를 호출합니다.

  int `use_environment`

    0보다 크면, 환경 변수를 사용합니다.

  int `user_site_directory`

    0이 아니면, 사용자 사이트 디렉터리를 `sys.path`에 추가합니다.

  int `verbose`

    0이 아니면, 상세 모드를 활성화합니다.

  PyWideStringList `warnoptions`

    `sys.warnoptions`: 경고 필터를 빌드하기 위한 `warnings` 모듈의 옵션: 가장 낮은 것에서 가장 높은 우선순위로.

    `warnings` 모듈은 `sys.warnoptions`를 역순으로 추가합니다: 마지막 `PyConfig.warnoptions` 항목은 가장 먼저 검사되는 `warnings.filters`의 첫 번째 항목이 됩니다 (가장 높은 우선순위).

  int `write_bytecode`

    0이 아니면, `.pyc` 파일을 기록합니다.

    `sys.dont_write_bytecode`는 `write_bytecode`의 반전된 값으로 초기화됩니다.

  PyWideStringList `xoptions`

    `sys._xoptions`.

  int `_use_peg_parser`

    PEG 구문 분석기를 활성화합니까? 기본값: 1.

    `-X oldparser`와 `PYTHONOLDPARSER`로 0으로 설정합니다.

    PEP 617도 참조하십시오.

    Deprecated since version 3.9, will be removed in version 3.10.

`parse_argv`가 0이 아니면, 일반 파이썬이 명령 줄 인자를 구문 분석하는 것과 같은 방식으로 `argv` 인자가 구문 분석되고, `argv`에서 파이썬 인자가 제거됩니다: 명령 줄 인자를 참조하십시오.

`xoptions` 옵션은 다른 옵션을 설정하기 위해 구문 분석됩니다: `-X` 옵션을 참조하십시오.

버전 3.9에서 변경: `show_alloc_count` 필드가 제거되었습니다.

## PyConfig를 사용한 초기화

파이썬을 초기화하는 함수:

PyStatus `Py_InitializeFromConfig`(const PyConfig *config)

  config 구성에서 파이썬을 초기화합니다.

호출자는 `PyStatus_Exception()`과 `Py_ExitStatusException()` 을 사용하여 예외(에러나 종료)를 처리해야 합니다.

If `PyImport_FrozenModules()`, `PyImport_AppendInittab()` or `PyImport_ExtendInittab()` are used, they must be set or called after Python preinitialization and before the Python initialization. If Python is initialized multiple times, `PyImport_AppendInittab()` or `PyImport_ExtendInittab()` must be called before each Python initialization.

프로그램 이름을 설정하는 예:

    void init_python(void)
    {
        PyStatus status;

        PyConfig config;
        PyConfig_InitPythonConfig(&config);

        /* Set the program name. Implicitly preinitialize Python. */
        status = PyConfig_SetString(&config, &config.program_name,
                                    L"/path/to/my_program");
        if (PyStatus_Exception(status)) {
            goto fail;
        }

        status = Py_InitializeFromConfig(&config);
        if (PyStatus_Exception(status)) {
            goto fail;
        }
        PyConfig_Clear(&config);
        return;

    fail:
        PyConfig_Clear(&config);
        Py_ExitStatusException(status);
    }

기본 구성을 수정하는 더 완전한 예, 구성을 읽은 다음 일부 파라미터를 대체합니다:

    PyStatus init_python(const char *program_name)
    {
        PyStatus status;

        PyConfig config;
        PyConfig_InitPythonConfig(&config);

        /* Set the program name before reading the configuration
           (decode byte string from the locale encoding).

           Implicitly preinitialize Python. */
        status = PyConfig_SetBytesString(&config, &config.program_name,
                                      program_name);
        if (PyStatus_Exception(status)) {
            goto done;
        }

        /* Read all configuration at once */
        status = PyConfig_Read(&config);
        if (PyStatus_Exception(status)) {
            goto done;
        }

        /* Append our custom search path to sys.path */
        status = PyWideStringList_Append(&config.module_search_paths,
                                         L"/path/to/more/modules");
        if (PyStatus_Exception(status)) {
            goto done;
        }

        /* Override executable computed by PyConfig_Read() */
        status = PyConfig_SetString(&config, &config.executable,
                                    L"/path/to/my_executable");
        if (PyStatus_Exception(status)) {
            goto done;
        }

        status = Py_InitializeFromConfig(&config);

    done:
        PyConfig_Clear(&config);
        return status;
    }

## 격리된 구성

`PyPreConfig_InitIsolatedConfig()`와 `PyConfig_InitIsolatedConfig()` 함수는 시스템에서 파이썬을 격리하는 구성을 만듭니다. 예를 들어, 파이썬을 응용 프로그램에 내장하기 위해.

This configuration ignores global configuration variables, environment variables, command line arguments (`PyConfig.argv` is not parsed) and user site directory. The C standard streams (ex: `stdout`) and the LC_CTYPE locale are left unchanged. Signal handlers are not installed.

구성 파일은 여전히 이 구성에 사용됩니다. 이러한 구성 파일을 무시하고 기본 경로 구성을 계산하는 함수를 피하려면 경로 구성( “출력 필드”) 을 설정하십시오.

## 파이썬 구성

`PyPreConfig_InitPythonConfig()`와 `PyConfig_InitPythonConfig()` 함수는 일반 파이썬처럼 동작하는 사용자 정의된 파이썬을 빌드하기 위한 구성을 만듭니다.

환경 변수와 명령 줄 인자는 파이썬을 구성하는 데 사용되는 반면, 전역 구성 변수는 무시됩니다.

이 함수는 LC_CTYPE 로케일, `PYTHONUTF8` 및 `PYTHONCOERCECLOCALE` 환경 변수에 따라 C 로케일 강제( PEP 538)와 UTF-8 모드( PEP 540)를 활성화합니다.

항상 격리 모드에서 실행되는 사용자 정의 파이썬의 예:

    int main(int argc, char **argv)
    {
        PyStatus status;

        PyConfig config;
        PyConfig_InitPythonConfig(&config);
        config.isolated = 1;

        /* Decode command line arguments.
           Implicitly preinitialize Python (in isolated mode). */
        status = PyConfig_SetBytesArgv(&config, argc, argv);
        if (PyStatus_Exception(status)) {
            goto fail;
        }

        status = Py_InitializeFromConfig(&config);
        if (PyStatus_Exception(status)) {
            goto fail;
        }
        PyConfig_Clear(&config);

        return Py_RunMain();

    fail:
        PyConfig_Clear(&config);
        if (PyStatus_IsExit(status)) {
            return status.exitcode;
        }
        /* Display the error message and exit the process with
           non-zero exit code */
        Py_ExitStatusException(status);
    }

## 경로 구성

`PyConfig`에는 경로 구성을 위한 여러 필드가 포함되어 있습니다:

- 경로 구성 입력:

  - `PyConfig.home`

  - `PyConfig.platlibdir`

  - `PyConfig.pathconfig_warnings`

  - `PyConfig.program_name`

  - `PyConfig.pythonpath_env`

  - 현재 작업 디렉터리: 절대 경로를 얻기 위해

  - (`PyConfig.program_name`에서) 프로그램 전체 경로를 얻기 위한 `PATH` 환경 변수

  - `__PYVENV_LAUNCHER__` 환경 변수

  - (윈도우 전용) HKEY_CURRENT_USER와 HKEY_LOCAL_MACHINE의 “SoftwarePythonPythonCoreX.YPythonPath” 아래에 있는 레지스트리의 응용 프로그램 경로 (여기서 X.Y는 파이썬 버전입니다).

- 경로 구성 출력 필드:

  - `PyConfig.base_exec_prefix`

  - `PyConfig.base_executable`

  - `PyConfig.base_prefix`

  - `PyConfig.exec_prefix`

  - `PyConfig.executable`

  - `PyConfig.module_search_paths_set`, `PyConfig.module_search_paths`

  - `PyConfig.prefix`

적어도 하나의 “출력 필드”가 설정되어 있지 않으면, 파이썬은 설정되지 않은 필드를 채우기 위해 경로 구성을 계산합니다. `module_search_paths_set`이 0이면, `module_search_paths`가 재정의되고 `module_search_paths_set`이 1로 설정됩니다.

위에 나열된 모든 경로 구성 출력 필드를 명시적으로 설정하여 기본 경로 구성을 계산하는 함수를 완전히 무시할 수 있습니다. 비어 있지 않아도 문자열은 설정된 것으로 간주합니다. `module_search_paths_set`이 1로 설정되면 `module_search_paths`는 설정된 것으로 간주합니다. 이 경우, 경로 구성 입력 필드도 무시됩니다.

경로 구성을 계산할 때 경고를 억제하려면 `pathconfig_warnings`를 0으로 설정하십시오 (유닉스 전용, 윈도우는 어떤 경고도 로그 하지 않습니다).

`base_prefix`나 `base_exec_prefix` 필드가 설정되지 않으면, 각각 `prefix`와 `exec_prefix`의 값을 상속합니다.

`Py_RunMain()`과 `Py_Main()`은 `sys.path`를 수정합니다:

- `run_filename`이 설정되고 `__main__.py` 스크립트를 포함하는 디렉터리이면, `run_filename`을 `sys.path` 앞에 추가합니다.

- `isolated`가 0이면:

  - `run_module`이 설정되면, 현재 디렉터리를 `sys.path` 앞에 추가합니다. 현재 디렉터리를 읽을 수 없으면 아무것도 하지 않습니다.

  - `run_filename`이 설정되면, 파일명의 디렉터리를 `sys.path` 앞에 추가합니다.

  - 그렇지 않으면, 빈 문자열을 `sys.path` 앞에 추가합니다.

`site_import`가 0이 아니면, `site` 모듈이 `sys.path`를 수정할 수 있습니다. `user_site_directory`가 0이 아니고 사용자의 site-package 디렉터리가 존재하면, `site` 모듈은 사용자의 site-package 디렉터리를 `sys.path`에 추가합니다.

다음과 같은 구성 파일이 경로 구성에 사용됩니다:

- `pyvenv.cfg`

- `python._pth` (윈도우 전용)

- `pybuilddir.txt` (유닉스 전용)

`__PYVENV_LAUNCHER__` 환경 변수는 `PyConfig.base_executable`을 설정하는 데 사용됩니다

## Py_RunMain()

int `Py_RunMain`(void)

  명령 줄이나 구성에서 지정된 명령 (`PyConfig.run_command`), 스크립트 (`PyConfig.run_filename`) 또는 모듈 (`PyConfig.run_module`)을 실행합니다.

  기본적으로, 그리고 `-i` 옵션을 사용할 때, REPL을 실행합니다.

  마지막으로, 파이썬을 파이널라이즈 하고 `exit()` 함수에 전달할 수 있는 종료 상태를 반환합니다.

`Py_RunMain()`을 사용하여 항상 격리 모드에서 실행되는 사용자 정의 파이썬의 예는 파이썬 구성을 참조하십시오.

## Py_GetArgcArgv()

void `Py_GetArgcArgv`(int *argc, wchar_t ***argv)

  파이썬이 수정하기 전의, 원래 명령 줄 인자를 가져옵니다.

## 다단계 초기화 비공개 잠정적 API

This section is a private provisional API introducing multi-phase initialization, the core feature of PEP 432:

- “핵심(Core)” 초기화 단계, “최소한의 파이썬”:

  - 내장형;

  - 내장 예외;

  - 내장과 프로즌 모듈(frozen modules);

  - `sys` 모듈은 부분적으로만 초기화됩니다 (예를 들어: `sys.path`는 아직 존재하지 않습니다).

- “주(Main)” 초기화 단계, 파이썬이 완전히 초기화됩니다:

  - `importlib`를 설치하고 구성합니다;

  - 경로 구성을 적용합니다;

  - 시그널 처리기를 설치합니다;

  - `sys` 모듈 초기화를 완료합니다 (예를 들어: `sys.stdout`과 `sys.path`를 만듭니다);

  - `faulthandler`와 `tracemalloc`과 같은 선택적 기능을 활성화합니다;

  - `site` 모듈을 임포트 합니다;

  - 등등

비공개 잠정적 API:

- `PyConfig._init_main`: 0으로 설정되면, `Py_InitializeFromConfig()`는 “핵심” 초기화 단계에서 중단합니다.

- `PyConfig._isolated_interpreter`: 0이 아니면, 스레드, 서브 프로세스 및 포크를 허용하지 않습니다.

PyStatus `_Py_InitializeMain`(void)

  “주” 초기화 단계로 이동하여, 파이썬 초기화를 완료합니다.

“핵심” 단계에서는 아무런 모듈도 임포트 하지 않고 `importlib` 모듈이 구성되지 않습니다: 경로 구성은 “주” 단계에서만 적용됩니다. 경로 구성을 재정의하거나 조정하기 위해 파이썬에서 파이썬을 사용자 정의할 수 있으며, 사용자 정의 `sys.meta_path` 임포터(importer)나 임포트 훅 등을 설치할 수 있습니다.

핵심 단계 이후에 주 단계 이전에 파이썬에서 경로 구성을 계산할 수 있게 될 수 있고, 이것이 PEP 432의 동기 중 하나입니다.

“핵심” 단계가 제대로 정의되지 않았습니다: 이 단계에서 무엇을 사용할 수 있고, 무엇이 그렇지 않아야 하는지는 아직 지정되지 않았습니다. API는 비공개이자 잠정적인 것으로 표시됩니다: 적절한 공개 API가 설계될 때까지 언제든지 API를 수정하거나 제거할 수 있습니다.

“핵심”과 “주” 초기화 단계 사이에서 파이썬 코드를 실행하는 예제:

    void init_python(void)
    {
        PyStatus status;

        PyConfig config;
        PyConfig_InitPythonConfig(&config);
        config._init_main = 0;

        /* ... customize 'config' configuration ... */

        status = Py_InitializeFromConfig(&config);
        PyConfig_Clear(&config);
        if (PyStatus_Exception(status)) {
            Py_ExitStatusException(status);
        }

        /* Use sys.stderr because sys.stdout is only created
           by _Py_InitializeMain() */
        int res = PyRun_SimpleString(
            "import sys; "
            "print('Run Python code before _Py_InitializeMain', "
                   "file=sys.stderr)");
        if (res < 0) {
            exit(1);
        }

        /* ... put more configuration code here ... */

        status = _Py_InitializeMain();
        if (PyStatus_Exception(status)) {
            Py_ExitStatusException(status);
        }
    }