# 모듈 객체

PyTypeObject `PyModule_Type`

  이 `PyTypeObject` 인스턴스는 파이썬 모듈 형을 나타냅니다. 이것은 `types.ModuleType`으로 파이썬 프로그램에 노출됩니다.

int `PyModule_Check`(PyObject *p)

  p가 모듈 객체이거나 모듈 객체의 서브 형이면 참을 반환합니다.

int `PyModule_CheckExact`(PyObject *p)

  p가 모듈 객체이지만, `PyModule_Type`의 서브 형이 아니면 참을 반환합니다.

PyObject* `PyModule_NewObject`(PyObject *name)
  Return value: New reference.

  `__name__` 어트리뷰트가 name으로 설정된 새 모듈 객체를 반환합니다. 모듈의 `__name__`, `__doc__`, `__package__` 및 `__loader__` 어트리뷰트가 채워집니다 (`__name__`을 제외하고 모두 `None`으로 설정됩니다); `__file__` 어트리뷰트를 제공하는 것은 호출자의 책임입니다.

  버전 3.3에 추가.

  버전 3.4에서 변경: `__package__`와 `__loader__`가 `None`으로 설정됩니다.

PyObject* `PyModule_New`(const char *name)
  Return value: New reference.

  `PyModule_NewObject()`와 비슷하지만, name이 유니코드 객체 대신 UTF-8로 인코딩된 문자열입니다.

PyObject* `PyModule_GetDict`(PyObject *module)
  Return value: Borrowed reference.

  module의 이름 공간을 구현하는 딕셔너리 객체를 반환합니다; 이 객체는 모듈 객체의 `__dict__` 어트리뷰트와 같습니다. module이 모듈 객체(또는 모듈 객체의 서브 형)가 아니면, `SystemError`가 발생하고 `NULL`이 반환됩니다.

  확장은 모듈의 `__dict__`를 직접 조작하지 말고 다른 `PyModule_*()`과 `PyObject_*()` 함수를 사용하는 것이 좋습니다.

PyObject* `PyModule_GetNameObject`(PyObject *module)
  Return value: New reference.

  module의 `__name__` 값을 반환합니다. 모듈이 제공하지 않거나, 문자열이 아니면, `SystemError`가 발생하고 `NULL`이 반환됩니다.

  버전 3.3에 추가.

const char* `PyModule_GetName`(PyObject *module)

  `PyModule_GetNameObject()`와 비슷하지만 `'utf-8'`로 인코딩된 이름을 반환합니다.

void* `PyModule_GetState`(PyObject *module)

  모듈의 “상태”, 즉 모듈 생성 시 할당된 메모리 블록을 가리키는 포인터나 `NULL`을 반환합니다. `PyModuleDef.m_size`를 참조하십시오.

PyModuleDef* `PyModule_GetDef`(PyObject *module)

  모듈이 만들어진 `PyModuleDef` 구조체에 대한 포인터나 모듈이 정의에서 만들어지지 않았으면 `NULL`을 반환합니다.

PyObject* `PyModule_GetFilenameObject`(PyObject *module)
  Return value: New reference.

  module의 `__file__` 어트리뷰트를 사용하여 module이 로드된 파일 이름을 반환합니다. 정의되지 않았거나 유니코드 문자열이 아니면, `SystemError`를 발생시키고 `NULL`을 반환합니다; 그렇지 않으면 유니코드 객체에 대한 참조를 반환합니다.

  버전 3.2에 추가.

const char* `PyModule_GetFilename`(PyObject *module)

  `PyModule_GetFilenameObject()`와 비슷하지만 ‘utf-8’로 인코딩된 파일명을 반환합니다.

  버전 3.2부터 폐지: `PyModule_GetFilename()`은 인코딩할 수 없는 파일명에 대해 `UnicodeEncodeError`를 발생시킵니다, 대신 `PyModule_GetFilenameObject()`를 사용하십시오.

## C 모듈 초기화

모듈 객체는 일반적으로 확장 모듈(초기화 함수를 내보내는 공유 라이브러리)이나 컴파일된 모듈(초기화 함수가 `PyImport_AppendInittab()`을 사용하여 추가된)에서 만들어집니다. 자세한 내용은 C와 C++ 확장 빌드하기나 내장된 파이썬을 확장하기를 참조하십시오.

초기화 함수는 모듈 정의 인스턴스를 `PyModule_Create()`에 전달하고 결과 모듈 객체를 반환하거나, 정의 구조체 자체를 반환하여 “다단계 초기화”를 요청할 수 있습니다.

`PyModuleDef`

  모듈 객체를 만드는 데 필요한 모든 정보를 담고 있는 모듈 정의 구조체. 일반적으로 각 모듈에 대해 이 형의 정적으로 초기화된 변수가 하나만 있습니다.

  PyModuleDef_Base `m_base`

    이 멤버를 항상 `PyModuleDef_HEAD_INIT`로 초기화하십시오.

  const char *`m_name`

    새 모듈의 이름.

  const char *`m_doc`

    모듈의 독스트링; 일반적으로 `PyDoc_STRVAR`로 만들어진 독스트링 변수가 사용됩니다.

  Py_ssize_t `m_size`

    모듈 상태는 정적 전역이 아닌 `PyModule_GetState()`로 조회할 수 있는 모듈별 메모리 영역에 유지될 수 있습니다. 이것은 여러 서브 인터프리터에서 모듈을 사용하는 것을 안전하게 만듭니다.

    이 메모리 영역은 모듈 생성 시 m_size를 기준으로 할당되며, 모듈 객체가 할당 해제될 때 (있다면 `m_free` 함수가 호출된 후에) 해제됩니다.

    `m_size`를 `-1`로 설정하면 모듈이 전역 상태를 갖기 때문에 서브 인터프리터를 지원하지 않는다는 뜻입니다.

    음수가 아닌 값으로 설정하면 모듈을 다시 초기화 할 수 있다는 뜻이며 상태에 필요한 추가 메모리양을 지정합니다. 다단계 초기화에는 음이 아닌 `m_size`가 필요합니다.

    자세한 내용은 PEP 3121을 참조하십시오.

  PyMethodDef* `m_methods`

    `PyMethodDef` 값으로 기술되는 모듈 수준 함수 테이블에 대한 포인터. 함수가 없으면 `NULL`일 수 있습니다.

  PyModuleDef_Slot* `m_slots`

    다단계 초기화를 위한 슬롯 정의 배열, `{0, NULL}` 항목으로 종료됩니다. 단단계 초기화를 사용할 때, m_slots는 `NULL`이어야 합니다.

    버전 3.5에서 변경: 버전 3.5 이전에는, 이 멤버가 항상 `NULL`로 설정되었으며, 다음과 같이 정의되었습니다:

    > inquiry `m_reload`

  traverseproc `m_traverse`

    모듈 객체의 GC 탐색 중 호출할 탐색 함수나, 필요하지 않으면 `NULL`. 이 함수는 모듈 상태가 할당되기 전에 (`PyModule_GetState()`가 NULL을 반환할 수 있습니다), 그리고 `Py_mod_exec` 함수가 실행되기 전에 호출될 수 있습니다.

  inquiry `m_clear`

    모듈 객체의 GC 정리 중에 호출할 정리(clear) 함수나, 필요하지 않으면 `NULL`. 이 함수는 모듈 상태가 할당되기 전에 (`PyModule_GetState()`가 NULL을 반환할 수 있습니다), 그리고 `Py_mod_exec` 함수가 실행되기 전에 호출될 수 있습니다.

  freefunc `m_free`

    모듈 객체 할당 해제 중에 호출할 함수나, 필요하지 않으면 `NULL`. 이 함수는 모듈 상태가 할당되기 전에 (`PyModule_GetState()`가 NULL을 반환할 수 있습니다), 그리고 `Py_mod_exec` 함수가 실행되기 전에 호출될 수 있습니다.

### 단단계 초기화

모듈 초기화 함수는 모듈 객체를 직접 만들고 반환할 수 있습니다. 이것을 “단단계 초기화”라고 하며, 다음 두 모듈 생성 함수 중 하나를 사용합니다:

PyObject* `PyModule_Create`(PyModuleDef *def)
  Return value: New reference.

  def의 정의에 따라, 새 모듈 객체를 만듭니다. 이것은 module_api_version이 `PYTHON_API_VERSION`으로 설정된 `PyModule_Create2()`처럼 동작합니다.

PyObject* `PyModule_Create2`(PyModuleDef *def, int module_api_version)
  Return value: New reference.

  def의 정의에 따라, API 버전 module_api_version을 가정하여 새 모듈 객체를 만듭니다. 해당 버전이 실행 중인 인터프리터 버전과 일치하지 않으면, `RuntimeWarning`을 발생시킵니다.

  참고

  이 함수는 대부분 `PyModule_Create()`를 대신 사용해야 합니다; 확실히 필요할 때만 사용하십시오.

초기화 함수에서 반환되기 전에, 결과 모듈 객체는 일반적으로 `PyModule_AddObject()`와 같은 함수를 사용하여 채워집니다.

### 다단계 초기화

확장을 지정하는 다른 방법은 “다단계 초기화”를 요청하는 것입니다. 이 방법으로 만들어진 확장 모듈은 파이썬 모듈과 더 비슷하게 동작합니다: 초기화는 모듈 객체가 만들어질 때의 생성 단계(creation phase)와 채워질 때의 실행 단계(execution phase)로 분할됩니다. 구별은 클래스의 `__new__()`와 `__init__()` 메서드와 유사합니다.

단단계 초기화를 사용하여 만들어진 모듈과 달리, 이 모듈은 싱글톤이 아닙니다: sys.modules 항목을 제거하고 모듈을 다시 임포트 하면, 새 모듈 객체가 만들어지고, 이전 모듈은 일반 가비지 수집이 적용됩니다 – 파이썬 모듈과 마찬가지입니다. 기본적으로, 같은 정의에서 만들어진 여러 모듈은 독립적이어야 합니다: 하나를 변경해도 다른 모듈에는 영향을 미치지 않습니다. 즉, 모든 상태는 모듈 객체(예를 들어 `PyModule_GetState()`를 사용해서)나 그 내용(가령 모듈의 `__dict__`나 `PyType_FromSpec()`으로 만든 개별 클래스)으로 제한되어야 합니다.

다단계 초기화를 사용하여 만들어진 모든 모듈은 서브 인터프리터를 지원할 것으로 기대됩니다. 다중 모듈을 독립적으로 유지하는 것은 일반적으로 이를 달성하기에 충분합니다.

다단계 초기화를 요청하기 위해, 초기화 함수(PyInit_modulename)는 비어 있지 않은 `m_slots`를 가진 `PyModuleDef` 인스턴스를 반환합니다. 반환되기 전에, `PyModuleDef` 인스턴스를 다음 함수를 사용하여 초기화해야 합니다:

PyObject* `PyModuleDef_Init`(PyModuleDef *def)
  Return value: Borrowed reference.

  모듈 정의가 형과 참조 횟수를 올바르게 보고하는 올바르게 초기화된 파이썬 객체이게 합니다.

  def를 `PyObject*`로 캐스트 하거나, 에러가 발생하면 `NULL`을 반환합니다.

  버전 3.5에 추가.

모듈 정의의 m_slots 멤버는 `PyModuleDef_Slot` 구조체의 배열을 가리켜야 합니다:

`PyModuleDef_Slot`
  int `slot`

    아래 설명된 사용 가능한 값 중에서 선택된, 슬롯 ID.

  void* `value`

    슬롯 ID에 따라 그 의미가 달라지는, 슬롯의 값.

  버전 3.5에 추가.

m_slots 배열은 id가 0인 슬롯으로 종료해야 합니다.

사용 가능한 슬롯 형은 다음과 같습니다:

`Py_mod_create`

  모듈 객체 자체를 만들기 위해 호출되는 함수를 지정합니다. 이 슬롯의 value 포인터는 다음과 같은 서명을 갖는 함수를 가리켜야 합니다:

  PyObject* `create_module`(PyObject *spec, PyModuleDef *def)

  이 함수는 PEP 451에 정의된 대로, `ModuleSpec` 인스턴스와 모듈 정의를 받습니다. 새 모듈 객체를 반환하거나, 에러를 설정하고 `NULL`을 반환해야 합니다.

  이 함수는 최소한으로 유지해야 합니다. 특히 같은 모듈을 다시 임포트 하려고 시도하면 무한 루프가 발생할 수 있어서, 임의의 파이썬 코드를 호출하면 안 됩니다.

  하나의 모듈 정의에서 여러 `Py_mod_create` 슬롯을 지정할 수 없습니다.

  `Py_mod_create`를 지정하지 않으면, 임포트 절차는 `PyModule_New()`를 사용하여 일반 모듈 객체를 만듭니다. 이름은 정의가 아니라 spec에서 취합니다, 확장 모듈이 단일 모듈 정의를 공유하면서 모듈 계층 구조에서 해당 위치에 동적으로 조정되고 심볼릭 링크를 통해 다른 이름으로 임포트 될 수 있도록 하기 위함입니다.

  반환된 객체가 `PyModule_Type`의 인스턴스 일 필요는 없습니다. 임포트 관련 어트리뷰트 설정과 읽기를 지원하는 한 모든 형을 사용할 수 있습니다. 그러나, `PyModuleDef`에 `NULL`이 아닌 `m_traverse`, `m_clear`, `m_free`; 0이 아닌 `m_size`; 또는 `Py_mod_create` 이외의 슬롯이 있으면, `PyModule_Type` 인스턴스 만 반환될 수 있습니다.

`Py_mod_exec`

  모듈을 실행하기 위해 호출되는 함수를 지정합니다. 이것은 파이썬 모듈의 코드를 실행하는 것과 동등합니다: 일반적으로, 이 함수는 클래스와 상수를 모듈에 추가합니다. 함수의 서명은 다음과 같습니다:

  int `exec_module`(PyObject* module)

  여러 개의 `Py_mod_exec` 슬롯이 지정되면, m_slots 배열에 나타나는 순서대로 처리됩니다.

다단계 초기화에 대한 자세한 내용은 PEP 489를 참조하십시오.

### 저수준 모듈 생성 함수

다단계 초기화를 사용할 때 수면 아래에서는 다음 함수가 호출됩니다. 이들은 직접 사용할 수 있는데, 예를 들어 모듈 객체를 동적으로 생성할 때 그렇습니다. 모듈을 완전히 초기화하려면 `PyModule_FromDefAndSpec`과 `PyModule_ExecDef`를 모두 호출해야 함에 유의하십시오.

PyObject * `PyModule_FromDefAndSpec`(PyModuleDef *def, PyObject *spec)
  Return value: New reference.

  주어진 모듈의 정의와 ModuleSpec spec으로 새 모듈 객체를 만듭니다. 이것은 module_api_version이 `PYTHON_API_VERSION`으로 설정된 `PyModule_FromDefAndSpec2()`처럼 동작합니다.

  버전 3.5에 추가.

PyObject * `PyModule_FromDefAndSpec2`(PyModuleDef *def, PyObject *spec, int module_api_version)
  Return value: New reference.

  API 버전 module_api_version을 가정하여, 주어진 모듈의 정의와 ModuleSpec spec으로 새 모듈 객체를 만듭니다. 해당 버전이 실행 중인 인터프리터 버전과 일치하지 않으면, `RuntimeWarning`을 발생시킵니다.

  참고

  이 함수는 대부분 `PyModule_FromDefAndSpec()`을 대신 사용해야 합니다; 확실히 필요할 때만 사용하십시오.

  버전 3.5에 추가.

int `PyModule_ExecDef`(PyObject *module, PyModuleDef *def)

  def에 지정된 모든 실행 슬롯(`Py_mod_exec`)을 처리합니다.

  버전 3.5에 추가.

int `PyModule_SetDocString`(PyObject *module, const char *docstring)

  module의 독스트링을 docstring으로 설정합니다. 이 함수는 `PyModule_Create`나 `PyModule_FromDefAndSpec`을 사용하여 `PyModuleDef`에서 모듈을 만들 때 자동으로 호출됩니다.

  버전 3.5에 추가.

int `PyModule_AddFunctions`(PyObject *module, PyMethodDef *functions)

  `NULL` 종료 functions 배열의 함수를 module에 추가합니다. 개별 항목에 대한 자세한 내용은 `PyMethodDef` 설명서를 참조하십시오 (공유 모듈 이름 공간이 없기 때문에, C로 구현된 모듈 수준 “함수(functions)”는 일반적으로 첫 번째 매개 변수로 모듈을 수신하여, 파이썬 클래스의 인스턴스 메서드와 유사하게 만듭니다). 이 함수는 `PyModule_Create`나 `PyModule_FromDefAndSpec`을 사용하여 `PyModuleDef`에서 모듈을 만들 때 자동으로 호출됩니다.

  버전 3.5에 추가.

### 지원 함수

모듈 초기화 함수(단단계 초기화를 사용하는 경우)나 모듈 실행 슬롯에서 호출되는 함수(다단계 초기화를 사용하는 경우)는, 모듈 상태 초기화를 도우려고 다음 함수를 사용할 수 있습니다:

int `PyModule_AddObject`(PyObject *module, const char *name, PyObject *value)

  name으로 module에 객체를 추가합니다. 모듈의 초기화 함수에서 사용할 수 있는 편의 함수입니다. 성공 시 value에 대한 참조를 훔칩니다. 에러 시 `-1`을, 성공하면 `0`을 반환합니다.

  참고

  참조를 훔치는 다른 함수와 달리, `PyModule_AddObject()`는 성공 시에만 value의 참조 횟수를 감소시킵니다.

  이는 반환 값을 확인해야 하며, 에러 시 호출하는 코드가 수동으로 value를 `Py_DECREF()` 해야 함을 뜻합니다. 사용법 예:

      Py_INCREF(spam);
      if (PyModule_AddObject(module, "spam", spam) < 0) {
          Py_DECREF(module);
          Py_DECREF(spam);
          return NULL;
      }

int `PyModule_AddIntConstant`(PyObject *module, const char *name, long value)

  module에 정수 상수를 name으로 추가합니다. 이 편의 함수는 모듈의 초기화 함수에서 사용할 수 있습니다. 에러 시 `-1`을, 성공하면 `0`을 반환합니다.

int `PyModule_AddStringConstant`(PyObject *module, const char *name, const char *value)

  module에 문자열 상수를 name으로 추가합니다. 이 편의 함수는 모듈의 초기화 함수에서 사용할 수 있습니다. 문자열 value는 `NULL`로 끝나야 합니다. 에러 시 `-1`을, 성공 시 `0`을 반환합니다.

int `PyModule_AddIntMacro`(PyObject *module, macro)

  module에 int 상수를 추가합니다. 이름과 값은 macro에서 취합니다. 예를 들어 `PyModule_AddIntMacro(module, AF_INET)`은 AF_INET 값을 가진 int 상수 AF_INET을 module에 추가합니다. 에러 시 `-1`을, 성공하면 `0`을 반환합니다.

int `PyModule_AddStringMacro`(PyObject *module, macro)

  module에 문자열 상수를 추가합니다.

## 모듈 조회

단단계 초기화는 현재 인터프리터의 컨텍스트에서 조회할 수 있는 싱글톤 모듈을 만듭니다. 이는 나중에 모듈 정의에 대한 참조만으로 모듈 객체를 검색할 수 있도록 합니다.

이 함수들은 다단계 초기화를 사용하여 만들어진 모듈에서는 작동하지 않습니다. 단일 정의에서 그러한 모듈이 여러 개 만들어질 수 있기 때문입니다.

PyObject* `PyState_FindModule`(PyModuleDef *def)
  Return value: Borrowed reference.

  현재 인터프리터에 대해 def에서 만들어진 모듈 객체를 반환합니다. 이 메서드를 사용하려면 먼저 모듈 객체가 `PyState_AddModule()`로 인터프리터 상태에 연결되어 있어야 합니다. 해당 모듈 객체를 찾을 수 없거나 인터프리터 상태에 아직 연결되지 않았으면, `NULL`을 반환합니다.

int `PyState_AddModule`(PyObject *module, PyModuleDef *def)

  함수에 전달된 모듈 객체를 인터프리터 상태에 연결합니다. 이는 `PyState_FindModule()`을 통해 모듈 객체에 액세스 할 수 있도록 합니다.

  단단계 초기화를 사용하여 만든 모듈에만 효과가 있습니다.

  파이썬은 모듈을 임포트 한 후 자동으로 `PyState_AddModule`을 호출하므로, 모듈 초기화 코드에서 호출하는 것은 불필요합니다 (하지만 무해합니다). 모듈의 자체 초기화 코드가 추후 `PyState_FindModule`을 호출하는 경우에만 명시적인 호출이 필요합니다. 이 함수는 주로 대안 임포트 메커니즘을 구현하기 위한 것입니다 (직접 호출하거나, 필요한 상태 갱신에 대한 자세한 내용에 대해 해당 구현을 참조함으로써).

  성공하면 0을, 실패하면 -1을 반환합니다.

  버전 3.3에 추가.

int `PyState_RemoveModule`(PyModuleDef *def)

  def에서 만들어진 모듈 객체를 인터프리터 상태에서 제거합니다. 성공하면 0을, 실패하면 -1을 반환합니다.

  버전 3.3에 추가.