2017-04-12 2 views
1

몇몇 파이썬 구조는 (언제 멈추는지를 알기 위해) 센티넬을 필요로하는 것 같습니다. 그렇다면 PyMethodDef의 배열과 같은 일부 요소의 경우, NULL 초로 초기화되는 감시 요소가있는 이유는 무엇입니까? 예를 zip를 들어PyMethodDef 배열에 다중 NULL을 포함하는 센티넬 요소가 필요한 이유는 무엇입니까?

:

static PyMethodDef zip_methods[] = { 
    {"__reduce__", (PyCFunction)zip_reduce, METH_NOARGS, reduce_doc}, 
    {NULL,   NULL}   /* sentinel */ 
}; 

왜 "센티넬 배열"의 마지막 PyMethodDefNULL의이 있습니까? 왜 1만이 아닌가? 또는 __reduce__에 4 개의 항목이있는 이유는 무엇입니까 4 NULL을 센티넬 요소로 사용 하시겠습니까?

+0

@Olaf 왜 C 태그를 제거합니까? 그것은 결국 여기에서 조사하고있는 C 코드입니다. – MSeifert

+0

"_ C가"멈춰야 할 때 "를 알 필요가 있다는 것을 깨닫습니다. - 그게 언어의 잘못이고 아무런 요구 사항이 아니며 C의 대부분의 배열에도 사용되지 않습니다. – Olaf

+0

아니요, 잘못 설정된 Python 구현을 조사하고 있습니다. 전제 조건. – Olaf

답변

3

나는 그렇게 생각하지 않습니다. 두 가지 이유 :

1) 파이썬 소스 코드에서는 NULL에 대해서만 이름을 검사합니다.

알고있는 한, PyMethodDef 어레이는 두 가지 장소에서 사용됩니다 : 유형에 메소드를 연결하고 메소드를 모듈에 연결할 때.

코드의 해당 비트를 찾으려면 모든 유형이 PyType_Ready이고 대부분 모듈이 PyModule_Init이므로 검색을 시작하십시오. PyModule_CreatePyModule_Create2으로 전달됩니다. PyType_Ready에서 메서드는 내부 함수 add_methods에 의해 처리됩니다. PyModule_Create2에는 낮은 레벨의 물건을 직접 처리하고 내부 기능을 _add_methods_to_object이라고 부르는 경우 실제로 public functionPyModule_AddFunctions을 호출합니다.

두 내부 함수에는 for 루프가있어 메서드를 반복하고 관련 사전에 추가합니다. bothcases에서 루핑을 계속하는 조건은 meth->ml_name!=NULL입니다.

따라서 적어도 현재는 이름 만 확인됩니다.

2) In both C and C++ partial initialization guarantees that the remaining fields are zero/default initialized. 따라서 센티넬의 첫 번째 요소를 0으로 초기화하면 다른 모든 요소가 0으로 초기화됩니다. {}도 사용할 수 있습니다.

(사이드 참고로, 파이썬은 거대하고는 거의 완전히에 작성 귀찮게 예를 PyTypeObject를 들어,이 자동 제로 초기화 그것을 정의하는 큰 구조체로 많이 사용합니다.)

이 대답 I를 작성 후 이것에는 already been discussed가다는 것을 것을을 발견했다. 그래서 요약


은 - 자동 제로 (즉 나는 그들이 비 NULL 방법과 NULL 이름에 대한 사용을 발견하면 향후 변경 될 수 있습니다 추측 있도록 구현 세부 비록)와 C 파이썬 만 ml_name을 확인 어쨌든 센티넬. 컨벤션이 왜 두 가지 요소를 설정하는 것으로 보이는지는 모르겠지만 컨벤션을 따르는 것으로부터 할 말이 있습니다.

관련 문제