파이썬 ==
과 차이점이 is
있습니까?
예, 그들은 매우 중요한 차이점이 있습니다.
==
: 동등성 점검-의미론은 동일한 오브젝트가 아닐 수도있는 동등한 오브젝트가 동일한 것으로 테스트한다는 것입니다. 현상태대로 설명서를 말한다 :
연산자 <,>, ==,> =, <= 및! =는 두 개체의 값을 비교합니다.
is
: 신원 확인-의미는 객체 (메모리에 보유 된) 가 객체라는 것입니다. 다시, 문서는 말합니다 :
연산자 is
및 is not
개체 식별을위한 테스트 : x is y
경우에만, 사실 x
과 y
같은 객체입니다. 객체 식별은 id()
기능을 사용하여 결정 됩니다. x is not y
역 진리 값을 산출합니다.
따라서 ID 확인은 객체의 ID가 같은지 확인하는 것과 같습니다. 그건,
a is b
와 같다:
id(a) == id(b)
where id
는 "함께 존재하는 객체들 사이에서 고유함을 보장하는"정수를 리턴하는 내장 함수이며 (참조 help(id)
) 그리고 어디에 a
그리고 b
임의의 객체입니다.
다른 사용법
이러한 의미를 의미론에 사용해야합니다. 사용 is
의 신원을 확인하고 ==
평등을 확인 할 수 있습니다.
따라서 일반적으로 is
신원 확인에 사용 합니다. 이것은 일반적으로 문서에서 "단일"이라고하는 메모리에 한 번만 존재해야하는 객체를 검사 할 때 유용합니다.
사용 사례는 is
다음과 같습니다.
None
- 열거 형 값 (enum 모듈에서 열거 형을 사용하는 경우)
- 일반적으로 모듈
- 일반적으로 클래스 정의에서 생성 된 클래스 객체
- 일반적으로 함수 정의로 인한 함수 객체
- 메모리에 한 번만 존재해야하는 다른 것 (일반적으로 모든 싱글 톤)
- 신원으로 원하는 특정 객체
일반적인 사용 사례는 ==
다음과 같습니다.
- 정수를 포함한 숫자
- 줄
- 기울기
- 세트
- 사전
- 커스텀 가변 객체
- 대부분의 경우 다른 내장 불변 객체
일반적인 사용 사례, 다시, 대한 ==
, 당신은하지 않을 수 있습니다 할 개체입니다 같은 대신이 될 수있다, 객체 상응 한
PEP 8 방향
표준 라이브러리를위한 공식 파이썬 스타일 가이드 인 PEP 8은 다음과 같은 두 가지 사용 사례를is
언급 합니다 .
싱글 톤과의 비교 None
는 항상 등호 연산자를 사용하지 않고 is
또는
로 수행해야합니다 is not
.
또한 if x
실제로 의미하는 if x is not None
경우 (예 : 기본적으로 변수 또는 인수가 None
다른 값으로 설정되어 있는지 테스트 할 때 ) 기록에주의하십시오 . 다른 값에는 부울 컨텍스트에서 false 일 수있는 유형 (예 : 컨테이너)이있을 수 있습니다!
동일성에서 평등 추론
만약 is
사실이라면, 평등은 일반적 으로 추론 될 수 있습니다 – 논리적으로, 만약 객체가 그 자체라면, 그것은 동등하게 테스트되어야합니다.
대부분의 경우이 논리는 사실이지만 __eq__
특수한 방법 의 구현에 의존합니다 . 문서에서 말한 것처럼
동등 비교 ( ==
및 !=
) 의 기본 동작 은 객체의 ID를 기반으로합니다. 따라서 동일한 ID를 가진 인스턴스를 동등하게 비교하면 동일하게되고 다른 ID를 가진 인스턴스를 동등하게 비교하면 불평등이 발생합니다. 이 기본 동작의 동기는 모든 객체가 반사적이어야한다는 요구입니다 (즉, x는 y는 x == y를 의미합니다).
일관성을 위해 다음 사항을 권장합니다.
평등 비교는 반사적이어야합니다. 다시 말해, 동일한 객체는 동일하게 비교해야합니다.
x is y
암시 x == y
이것이 커스텀 객체의 기본 동작임을 알 수 있습니다.
>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)
반대되는 것도 일반적으로 사실입니다. 만약 무언가가 동일하지 않은 것으로 테스트된다면, 당신은 그것들이 같은 객체가 아니라고 추론 할 수 있습니다.
평등에 대한 테스트를 사용자 정의 할 수 있으므로이 유추가 모든 유형에 대해 항상 적용되는 것은 아닙니다.
예외
주목할만한 예외는 nan
항상 자신과 같지 않은 것으로 테스트합니다.
>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan # !!!!!
False
동일성을 확인하는 것보다 신원을 확인하는 것이 훨씬 빠릅니다 (재귀 적으로 멤버를 확인해야 할 수도 있음).
그러나 둘 이상의 객체를 동등한 것으로 찾을 수있는 동일성을 대체 할 수는 없습니다.
목록과 튜플의 동등성을 비교하면 객체의 동일성이 동일하다고 가정합니다 (빠른 검사이기 때문에). 논리가 일치하지 않으면 다음과 같이 모순이 발생할 수 있습니다 nan
.
>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True
주의 사항 :
문제는 is
정수를 비교하는 데 사용하려고합니다 . 정수의 인스턴스가 다른 참조에서 얻은 인스턴스와 동일한 인스턴스라고 가정해서는 안됩니다. 이 이야기는 이유를 설명합니다.
주석 작성자는 작은 정수 (-5 ~ 256 포함)가 동등성을 검사하는 대신 파이썬에서 싱글 톤이라는 사실에 의존하는 코드를 가지고있었습니다.
와우, 이것은 교활한 버그로 이어질 수 있습니다. a와 b가 일반적으로 작은 숫자이기 때문에 a가 b인지 확인하는 코드가 있습니다. a와 b가 결국 캐시되지 않을 정도로 커졌기 때문에 버그는 현재 6 개월이 지난 후에야 발생했습니다. – gwg
그것은 개발에 일했다. 일부 단위 테스트를 통과했을 수 있습니다.
그리고 코드가 256보다 큰 정수를 검사하기 전까지는 프로덕션 환경에서 작동했습니다.이 시점에서 프로덕션에서 실패했습니다.
이는 코드 검토 또는 스타일 검사기에서 발생할 수있는 프로덕션 실패입니다.
강조하겠습니다 : 정수를 비교 하는 is
데 사용하지 마십시오 .
echo 'import sys;tt=sys.argv[1];print(tt is "foo", tt == "foo", id(tt)==id("foo"))'| python3 - foo
output :False True False
.