정의 슬롯¶
C API를 사용하여 모듈 객체 및 클래스 를 정의할 때 슬롯 배열을 사용할 수 있습니다. 슬롯은 기본적으로 생성할 객체의 특징을 기술하는 키-값 쌍입니다. 이를 통해 데이터와 실행 시 사용되는 구조를 분리함으로써, CPython 및 기타 Python C API 구현이 하위 호환성을 깨뜨리지 않으면서도 구조를 업데이트할 수 있게 됩니다.
이 섹션은 슬롯에 대해 일반적인 내용을 다룹니다. 객체별 동작 및 슬롯 값에 대해서는 슬롯을 적용하는 함수들의 문서를 참조하십시오.
형(type)의 경우
PyType_FromSlots();모듈의 경우
PyModule_FromSlotsAndSpec()및 확장 내보내기 후크;
슬롯이 이를 적용하는 함수로 전달될 때, 해당 함수는 슬롯 배열이나 그가 가리키는 데이터(재귀적)를 수정하지 않습니다. 함수 실행이 끝난 후 호출자는 PySlot_STATIC 으로 명시적으로 표시된 데이터를 제외하고, 배열과 그가 가리키는 모든 데이터(재귀적)를 수정하거나 해제할 수 있습니다.
별도로 명시되지 않는 한, 단일 슬롯 배열 내에 동일한 ID(sl_id)를 가진 여러 개의 슬롯이 존재할 수 없습니다.
Added in version 3.15: 슬롯 배열은 이전의 객체 정의 방식을 일반화한 것입니다. 즉, 타입에는 PyType_Spec 과 PyType_Slot 을 사용하고, 모듈에는 PyModuleDef 와 PyModuleDef_Slot 을 사용하는 방식입니다. 이전 API는 soft deprecated 상태이며, 삭제 계획은 없습니다.
슬롯 배열의 항목은 다음 구조를 사용합니다.
-
type PySlot¶
- …의 일부 안정 ABI (모든 멤버 포함) 버전 3.15 이후로.
슬롯 배열의 항목입니다. 다음과 같이 정의됩니다.
typedef struct { uint16_t sl_id; uint16_t sl_flags; uint32_t _reserved; // must be 0 union { void *sl_ptr; void (*sl_func)(void); Py_ssize_t sl_size; int64_t sl_int64; uint64_t sl_uint64; }; } PySlot;
-
uint16_t sl_id¶
다음 중 선택된 슬롯 ID:
0인
sl_id(Py_slot_end)는 슬롯 배열의 끝을 나타냅니다.
-
void *sl_ptr¶
-
void (*sl_func)(void)¶
-
Py_ssize_t sl_size¶
-
int64_t sl_int64¶
-
uint64_t sl_uint64¶
슬롯에 대한 데이터입니다. 이 멤버들은 익명 유니온(anonymous union)의 일부이며, 슬롯 ID에서 요구하는 데이터 유형에 따라 사용할 멤버가 달라집니다: 각각 데이터 포인터, 함수 포인터, 크기, 부호 있는 정수 또는 부호 없는 정수입니다.
특정 슬롯 ID에 대해 별도로 명시되지 않는 한, 포인터(즉,
sl_ptr및sl_func)는 NULL일 수 없습니다.
-
uint16_t sl_flags¶
다음 플래그 중 0개 이상의 항목을 비트별 OR 연산으로 결합한 값입니다.
-
PySlot_STATIC¶
- …의 일부 안정 ABI 버전 3.15 이후로.
슬롯이 가리키는 모든 데이터는 정적으로 할당되고 고정된 값입니다. 따라서 인터프리터가 이 정보를 복사할 필요가 없습니다.
이 플래그는 함수 포인터의 경우 암시적으로 적용됩니다.
이 플래그는 슬롯이 ‘간접적으로’ 가리키는 데이터에도 적용됩니다. 단,
Py_slot_subslots를 통해 중첩된 슬롯의 경우 별도의PySlot_STATIC플래그를 가질 수 있습니다. 예를 들어,PyMemberDef구조체 배열을 가리키는Py_tp_members슬롯에 이 플래그가 적용되면, 전체 배열과 각 요소의 이름 및 독스트링이 모두 정적이고 고정된 값이어야 합니다.
-
PySlot_INTPTR¶
- …의 일부 안정 ABI 버전 3.15 이후로.
데이터는
sl_ptr에 저장되며, CPython이 이를 적절한 타입으로 캐스팅합니다.이 플래그는 기존의
PyType_Slot및PyModuleDef_Slot구조체에서 이식하는 과정을 간소화할 수 있습니다.
-
PySlot_STATIC¶
Added in version 3.15.
-
uint16_t sl_id¶
편의용 매크로¶
-
PySlot_DATA(name, value)¶
-
PySlot_FUNC(name, value)¶
-
PySlot_SIZE(name, value)¶
-
PySlot_INT64(name, value)¶
-
PySlot_UINT64(name, value)¶
-
PySlot_STATIC_DATA(name, value)¶
- …의 일부 안정 ABI 버전 3.15 이후로.
sl_id및 특정 유니온 멤버 세트를 포함하는PySlot구조를 정의하기 위한 편의용 매크로입니다.PySlot_STATIC_DATA는PySlot_STATIC플래그를 설정합니다. 다른 매크로는 플래그를 설정하지 않습니다.이 매크로들은 C++ 표준 2020 버전부터 추가된 C 언어 기능인 지정 초기화(designated initializers) 를 사용합니다. 코드가 C++11 이하와 호환되어야 하는 경우 대신
PySlot_PTR을 사용하십시오.다음과 같이 정의됨:
#define PySlot_DATA(NAME, VALUE) \ {.sl_id=NAME, .sl_ptr=(void*)(VALUE)} #define PySlot_FUNC(NAME, VALUE) \ {.sl_id=NAME, .sl_func=(VALUE)} #define PySlot_SIZE(NAME, VALUE) \ {.sl_id=NAME, .sl_size=(VALUE)} #define PySlot_INT64(NAME, VALUE) \ {.sl_id=NAME, .sl_int64=(VALUE)} #define PySlot_UINT64(NAME, VALUE) \ {.sl_id=NAME, .sl_uint64=(VALUE)} #define PySlot_STATIC_DATA(NAME, VALUE) \ {.sl_id=NAME, .sl_flags=PySlot_STATIC, .sl_ptr=(VALUE)}
Added in version 3.15.
-
PySlot_END¶
- …의 일부 안정 ABI 버전 3.15 이후로.
PySlot배열의 끝을 표시하는 편의용 매크로입니다.다음과 같이 정의됨:
#define PySlot_END {0}Added in version 3.15.
-
PySlot_PTR(name, value)¶
-
PySlot_PTR_STATIC(name, value)¶
- …의 일부 안정 ABI 버전 3.15 이후로.
C++11 호환 코드를 위한 편의용 매크로입니다. 이 버전의 C++에서는 리터럴에서 임의의 유니온 멤버를 설정하는 것을 허용하지 않으므로, 대신 이 매크로들은
PySlot_INTPTR플래그를 설정하고 값을(void*)로 캐스팅합니다.다음과 같이 정의됨:
#define PySlot_PTR(NAME, VALUE) \ {NAME, PySlot_INTPTR, {0}, {(void*)(VALUE)}} #define PySlot_PTR_STATIC(NAME, VALUE) \ {NAME, PySlot_INTPTR|Py_SLOT_STATIC, {0}, {(void*)(VALUE)}}
Added in version 3.15.
공통 슬롯 ID¶
다음 슬롯 ID들은 타입 및 모듈 정의 모두에서 사용될 수 있습니다.
-
Py_slot_subslots¶
- …의 일부 안정 ABI 버전 3.15 이후로.
중첩된 슬롯 배열.
sl_ptr값은PySlot구조체 배열을 가리켜야 합니다. 현재 슬롯 배열의Py_slot_subslots이 나타나는 지점에서, 해당 배열 내의 슬롯들(ID가 0인 종료자를 포함하지 않음)은 마치 원래 그 위치에 삽입된 것처럼 처리됩니다.슬롯 중첩 깊이는 5단계로 제한됩니다. 이 제한은 향후 해제될 수 있습니다.
Added in version 3.15.
-
Py_slot_invalid¶
- …의 일부 안정 ABI 버전 3.15 이후로.
예약됨; 항상 알 수 없는 슬롯 ID로 취급됩니다.
UINT16_MAX``(``0xFFFF)로 정의됩니다.PySlot_OPTIONAL플래그와 함께 사용될 때 효과가 없는 슬롯을 정의합니다. 해당 플래그 없이는 이 ID를 가진 슬롯을 처리할 때 오류가 발생합니다.Added in version 3.15.