왜 (0-6)이 -6 = False입니까? [복제]
가능한 중복 :
파이썬“is”연산자는 정수로 예기치 않게 동작합니다
오늘 나는 내 프로젝트를 디버깅하려고 시도했으며 몇 시간 동안 분석 한 후에 이것을 얻었습니다.
>>> (0-6) is -6
False
그러나,
>>> (0-5) is -5
True
왜 나에게 설명해 주시겠습니까? 아마도 이것은 일종의 버그이거나 매우 이상한 행동 일 것입니다.
> Python 2.7.3 (default, Apr 24 2012, 00:00:54) [GCC 4.7.0 20120414 (prerelease)] on linux2
>>> type(0-6)
<type 'int'>
>>> type(-6)
<type 'int'>
>>> type((0-6) is -6)
<type 'bool'>
>>>
-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까지입니다. 많은 Python 프로그램은 해당 범위의 정수를 사용하여 많은 시간을 소비하므로 현명한 결정입니다.
이것은 CPython의 구현 세부 사항 일 뿐이며 이에 의존해서는 안됩니다. 예를 들어, PyPyid
는 정수를 구현하여 자체를 리턴하므로 (0-6) is -6
내부적으로 "다른 오브젝트"인 경우에도 항상 참입니다. 또한이 정수 캐싱 사용 여부를 구성하고 하한 및 상한을 설정할 수도 있습니다. 그러나 일반적으로 다른 원점에서 검색된 객체는 동일하지 않습니다. 평등을 비교하려면을 사용하십시오 ==
.
파이썬은 인터프리터에 -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()
에 대한 사실이 아니다, 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
문자열 캐싱에 대한 자세한 내용은 is
문자열을 공백과 비교할 때 연산자가 다르게 동작합니다.
참고URL : https://stackoverflow.com/questions/11476190/why-0-6-is-6-false
'programing tip' 카테고리의 다른 글
Math.random () 설명 (0) | 2020.07.02 |
---|---|
종속성 속성이란 무엇입니까? (0) | 2020.07.02 |
포트는 IPv6에서 어떻게 작동합니까? (0) | 2020.07.02 |
"배치"란 무엇이며 GO가 사용되는 이유는 무엇입니까? (0) | 2020.07.01 |
xcode4의 프레임 워크와 정적 라이브러리의 차이점과 호출 방법 (0) | 2020.07.01 |