파이썬에 중첩 될 수있는 정적 블록의 수에 제한이있는 이유는 무엇입니까?
파이썬에서 정적으로 중첩 된 블록의 수는 20 개로 제한됩니다. 즉, 19 개의 for
루프를 중첩하는 것은 괜찮습니다 (과도하게 시간이 많이 걸리지 O(n^19)
만 제정신이 아닙니다) . 20 개의 중첩은 다음과 같이 실패합니다.
SyntaxError: too many statically nested blocks
그러한 제한이있는 근본적인 이유는 무엇입니까? 한도를 늘리는 방법이 있습니까?
이 제한은 for
루프뿐만 아니라 다른 모든 제어 흐름 블록에도 적용됩니다. 중첩 된 제어 흐름 블록 수에 대한 제한은 다음 과 같은 상수를 사용하여 code.h 내부에 정의됩니다 CO_MAXBLOCKS
.
#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
이 상수는 파이썬이라는 이름의 예외와 루프를 실행하는 데 사용하는 스택의 최대 크기를 설정하는 데 사용됩니다 blockstack
. 이 제한은 모든 프레임 객체에 적용되며 frameobject.h에 표시됩니다 .
int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */
이 제한의 가장 가능성있는 이유는 중첩 된 블록을 실행할 때 메모리 사용량을 정상 수준으로 유지하기위한 것입니다. 파이썬이 재귀 호출에 부과하는 제한 과 비슷할 것입니다 . 이 제한은 compile.c 에서 적용되는 것을 볼 수 있습니다 .
if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
PyErr_SetString(PyExc_SyntaxError,
"too many statically nested blocks");
return 0;
}
파이썬이 왜 이런 특정한 제한을 가지고 있고 왜 그것을 제거 할 수 없는지에 대한 더 구체적인 대답 은 2004 년 파이썬 메일 링리스트 편지에서 마이클 허드슨 이 제공했습니다 :
에 딱 맞다. 이것은 파이썬 구현에 대한 내부 세부 사항 인 '블록 스택'과 관련이 있습니다. 우리는 (그것을 제거하고자 하지 우리는 사람들이 For 루프를 20 개 이상으로 코드를 작성할 수 있도록 원하기 때문에 :-)하지만 특히 쉬운 일이 아닙니다 (마지막 : 블록) 가장 큰 문제입니다.
파이썬 2.6 이하에서, 중첩 루프의 최대 수를 파괴하는 원인했습니다 것이라는 점을주의 SystemError
하지 않는 SyntaxError
. 그러나 이것은 Python 3에서 변경되었으며 Python 2.7로 백 패치되었으므로 SyntaxError
대신 a 가 발생합니다. 이것은 #issue 27514 에 문서화되었습니다 .
문제 # 27514 : 정적으로 중첩 된 블록이 너무 많으면 SystemError 대신 SyntaxError가 발생합니다.
예외 유형이 변경된 이유는 Serhiy Storchaka 가 제공했습니다 .
[...] SystemError는 발생해야하는 예외가 아닙니다. SystemError는 정상적인 경우에 발생할 수없는 오류입니다. C API를 잘못 사용하거나 Python 내부를 해킹 한 경우에만 발생해야합니다. 이 경우 SyntaxError가 더 적절하다고 생각합니다 [...].
이는 blockstack
바이트 코드 주소의 스택 인와 관련이 있으며 루프 및 예외와 같은 코드 블록을 실행하는 데 사용됩니다.
C 버전 (C99 이전)이이 제한을로 설정 20
했고 CPython 인터프리터가 C로 빌드 되었으므로 동일한 규칙을 따랐습니다 .
#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
상수 20
는 관습에서 벗어난 것으로 보입니다.
[링크 제공 : Christian Dean.]
한도가 20 인 이유는 무엇입니까?
관습의 주장이 설득력이 없다면 The Zen of Python을 살펴보십시오 .
In [4]: import this
The Zen of Python, by Tim Peters
...
Flat is better than nested.
...
이 가치를 어떻게 높일 수 있습니까?
이 값은 하드 코딩 된 상수이므로 프로그램에 적용되도록 변경하는 유일한 방법은 Python 배포를 다시 빌드하고 새 빌드에서 스크립트를 실행하는 것입니다.
github 에서 cpython 소스 코드 다운로드
로 이동
cpython/Include/code.h
의 값을
CO_MAXBLOCKS
20보다 큰 값으로 변경하십시오.파이썬 재 컴파일 (테스트 비활성화, 불평 할 것임 )
여기 대답을 참조하십시오 : 정적으로 중첩 된 블록이 너무 많습니다 python 파이썬 구문에 내장되어 있으므로 늘릴 수 없습니다. 제한은 모든 종류의 코드 스택 (예외, 루프 등)에 적용되며 디자이너가 결정한 것입니다 (아마도 메모리 사용을 합리적으로 유지하기 위해). 한 가지 이상한 점은 여기에 있습니다 : https://github.com/python/cpython/blob/6f0eb93183519024cb360162bdd81b9faec97ba6/Include/code.h#L95 는 (20)가 최대 수를 말한다 함수 . 하지만 함수 내부가 아닌 23 개의 for 루프를 중첩하려고 시도했지만 여전히 오류가 발생합니다.
'development' 카테고리의 다른 글
Rpresentation Markdown에서 실행되지 않는 코드 포함 (0) | 2020.12.08 |
---|---|
오류 : 원인 : buildToolsVersion이 지정되지 않았습니다. (0) | 2020.12.08 |
R 스크립트의 경로 얻기 (0) | 2020.12.08 |
NSString과 함께 printf를 사용하는 방법 (0) | 2020.12.08 |
요청 라이브러리를 사용하는 Python 앱 단위 테스트 (0) | 2020.12.08 |