is**는 객체의 아이덴티티를 비교합니다(즉, 변수가 동일한 메모리 영역을 가리키고 있는지 여부).==(operator eq)는 값을 비교합니다. 즉, 객체의 내용 측면에서 같은지 여부를 확인합니다.**is**는 아이덴티티(예: None 또는 singleton 객체와의 비교)를 비교하는 데 사용해야 하며 값의 동등성을 확인하는 데 사용해서는 안 됩니다.
예:
a = [1, 2, 3] b = [1, 2, 3] print(a == b) # True print(a is b) # False c = None d = None print(c is d) # True
작은 정수나 문자열을 사용할 때는 인터프리터가 "인터니징"(캐시된 객체)을 사용할 수 있으며, 이로 인해 is가 같은 값에 대해 True가 될 수 있지만, 이러한 방식은 프로그램 로직에서 사용해서는 안 됩니다.
질문: 다음 코드는 무엇을 출력합니까?
a = 256 b = 256 print(a is b) c = 257 d = 257 print(c is d)왜 그렇죠?
답변:
-5에서 256 사이의 값에 대해 파이썬은 정수 풀을 사용합니다. 이 범위의 값들은 항상 동일한 객체를 가리키므로 a is b는 True를 반환합니다. 257은 이미 풀을 벗어났기 때문에 c is d는 False가 됩니다(객체가 독립적입니다).
역사
하나의 마이크로서비스에서 문자열의 동등성 검사를 위해 is를 사용했으나 ==를 사용하지 않았습니다. 인터프리터의 최적화 덕분에 프로그램이 테스트에서 "안정적으로" 작동했지만, 재컴파일이나 환경의 다른 변경 후에는 오류가 발생했습니다.
한 개발자가 숫자를 비교하기 위해 is 연산자를 사용했으나 ==를 사용하지 않았습니다. 이것은 작은 숫자에서 작동했지만(풀 덕분에) 큰 숫자에서는 오류 및 예측할 수 없는 결과를 초래했습니다. 이는 계산 작업의 부정확한 결과를 유발했습니다.
인증 시스템 설계에서 들어온 JSON을 is None을 사용해 검사했으나(올바르게) 문자열에 대해서도 유사하게 if status is "ok" 방식으로 했습니다. 이는 오류로 판명되었습니다 — 때때로 조건이 충족되지 않아 데이터 처리의 잘못된 로직을 초래했습니다.