Python의 미리 정의된 상수는 꽤 이상함

1 day ago 6

Python의 미리 정의된 상수 6개인 True, False, None, __debug__, Ellipsis·..., NotImplemented는 이름 해석과 대입 규칙이 제각각임 True, False, None은 식별자가 아닌 어휘 토큰이어서 x.True 같은 속성 접근도 SyntaxError를 일으킴 __debug__는 일반 식별자처럼 속성을 조회할 수 있지만 직접 대입할 수 없는 유일한 식별자이며, -O로 실행하면 True에서 False로 바뀜 Ellipsis와 NotImplemented는 일반 내장 이름이라 전역 변수나 builtins 수정으로 덮어쓸 수 있지만, 어휘 토큰 ...은 영향을 받지 않음 builtins.True나 builtins.__debug__를 setattr로 바꿔도 코드의 True와 __debug__는 그대로여서, 문서상 같은 상수 범주에서도 실제 불변성은 일관되지 않음 상수마다 다른 문법과 오류 True, False, None은 일반적인 이름 해석을 거치지 않는 키워드이자 독립된 어휘 토큰임 식별자가 아니므로 x.True는 속성 조회가 아니라 SyntaxError가 됨 __debug__는 보통 True이며, Python을 -O로 실행하면 False로 바뀜 최적화 빌드에서 비용이 큰 검사를 제외하려면 if __debug__로 감쌀 수 있음 키워드가 아닌 일반 식별자 형태지만 __debug__ = 67과 x.__debug__ = 67은 모두 SyntaxError가 됨 반면 x.__debug__ 조회는 문법적으로 유효하므로 해당 속성이 없으면 AttributeError 가 발생함 삭제에는 대입과 다른 규칙이 적용됨 del __debug__에는 cannot delete __debug__라는 특별한 SyntaxError가 발생함 del x.__debug__는 특별 처리되지 않아 x가 없으면 NameError, 속성이 없으면 AttributeError가 발생함 __debug__ 대입은 문법 자체가 잘못되지 않았는데도 SyntaxError로 처리됨 assert (__debug__ := 67)은 디버그 실행에서 SyntaxError가 나지만, -O에서는 assert가 컴파일되지 않아 예외도 발생하지 않음 함수 밖의 assert (yield)와 assert (await 67)도 비슷하게 동작함 내장 이름을 덮어쓸 때 드러나는 차이 Ellipsis와 NotImplemented는 문서의 상수 항목에 속...

Read Entire Article