programing

왜 (0-6)이 -6 = 거짓입니까?

bestprogram 2023. 7. 21. 21:47

왜 (0-6)이 -6 = 거짓입니까?

일부 코드를 디버깅하는 동안 이상한 점을 발견했습니다.보아하니,

>>> (0-6) is -6
False

그렇지만,

>>> (0-5) is -5
True

왜 이런 일이 일어날까요?

-5에서 256까지의 모든 정수는 CPython과 동일한 주소를 공유하는 글로벌 개체로 캐시됩니다.is시험 합격

이 아티팩트는 http://www.laurentluce.com/posts/python-integer-objects-implementation/, 에 자세히 설명되어 있으며 http://hg.python.org/cpython/file/tip/Objects/longobject.c 에서 현재 소스 코드를 확인할 수 있습니다.

특정 구조를 사용하여 작은 정수를 참조하고 공유하므로 액세스가 빠릅니다.정수 객체에 대한 262개의 포인터 배열입니다.이러한 정수 객체는 위에서 본 정수 객체 블록에서 초기화 중에 할당됩니다.작은 정수 범위는 -5 ~ 256입니다.많은 파이썬 프로그램은 해당 범위의 정수를 사용하는 데 많은 시간을 소비하므로 이는 현명한 결정입니다.

이것은 CPython의 구현 세부사항일 뿐이며 이에 의존해서는 안 됩니다.예를 들어, PyPy는 다음을 구현했습니다.id정수가 자신을 반환하는 것, 그래서.(0-6) is -6는 내부적으로 "다른 개체"인 경우에도 항상 true이며, 이 정수 캐싱을 사용할지 여부를 구성하고 하한 및 상한을 설정할 수도 있습니다.그러나 일반적으로 다른 기원에서 검색된 개체는 동일하지 않습니다.동일성을 비교하려면 다음을 사용합니다.==.

Python은 인터프리터에 -5 - 256 범위의 정수를 저장합니다. 즉, 정수가 반환되는 정수 객체 풀이 있습니다.그렇기 때문에 이러한 개체는 동일합니다.(0-5)그리고.-5하지만 아닙니다.(0-6)그리고.-6이것들이 즉석에서 만들어지기 때문에.

CPython 소스 코드의 소스는 다음과 같습니다.

#define NSMALLPOSINTS           257
#define NSMALLNEGINTS           5
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];

(CPython 소스 코드 보기:/trunk/Objects/intobject.c). 소스 코드에는 다음과 같은 주석이 포함됩니다.

/* References to small integers are saved in this array so that they
   can be shared.
   The integers that are saved are those in the range
   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/

is그런 다음 운영자가 이들을 비교).-5동일한 객체(같은 메모리 위치)이지만 다른 두 개의 새로운 정수(-6) 다른 메모리 위치에 있을 것입니다.is돌아오지 않음True). 참고:257위의 소스 코드는 양의 정수에 대한 것이므로 다음과 같습니다.0 - 256(계속).

(소스)

벌레가 아닙니다.is동등성 검정이 아닙니다.==예상 결과를 제공합니다.

이 동작의 기술적 이유는 Python 구현이 동일한 상수 값의 다른 인스턴스를 동일한 개체 또는 다른 개체로 자유롭게 처리할 수 있기 때문입니다.사용 중인 Python 구현체는 메모리 절약을 위해 특정 작은 상수를 동일한 객체를 공유하도록 선택합니다.이 동작은 버전 간 또는 다른 Python 구현 간에 동일한 버전이어야 합니다.

이 일부 한 CPython을 제공하기 에 발생합니다.id().

(0-5)그리고.-5에 대해 동일한 값을 가집니다.id()은 에있서사아닌실이는어▁for아닌에 해당되지 .0-6그리고.-6

>>> id((0-6))
12064324
>>> id((-6))
12064276
>>> id((0-5))
10022392
>>> id((-5))
10022392

문자열의 경우도 마찬가지입니다.

>>> x = 'abc'
>>> y = 'abc'
>>> x is y
True
>>> x = 'a little big string'
>>> y = 'a little big string'
>>> x is y
False

문자열 캐싱에 대한 자세한 내용은 문자열을 공백과 비교할 연산자가 다르게 동작하는 경우를 참조하십시오.

언급URL : https://stackoverflow.com/questions/11476190/why-0-6-is-6-false