PEP8 프로그래밍 권고에는 파이썬에서 값을 비교할때 사용할 방법에 관하여 서술하고 있습니다. 내용을 살펴보면 아래와 같습니다.
is/is not
을 사용하고 ==/!=
연산자는 사용하지 않는다.if x
문을 작성할 때는 if x is None/not None
/ if x is
True/False
인지 구분해서 사용해라.boolean
값을 ==/!=
연산자를 사용해서 True
/False
인지 비교하지 않는다.True/False
를 비교할 때는 if문
에 변수만 사용한다.==/!=
연산자를 사용한다.is/is not
을 사용한다.이와 같은 가이드라인은 동일성과 동등성에 관한 내용입니다. 뿐만 아니라 위와 같은 가이드라인을 따른다면 가독성과 코드의 효율성도 높아지고, 잘못된 비교방식으로 인한 잘못된 결과를 나오는 것을 방지할 수 있습니다.
Idendtity
는 동일성을 검증하는 것입니다. 즉 변수에 할당된 객체가 같은 객체인지 메모리 주소값을 비교하여 검증하는 것입니다. 반면 Equality
는 동등성을 검증하는 것입니다. 변수에 할당된 객체가 주소가 다르더라도 값이 동등한 것인지 검증하는 것입니다. 이러한 비교 방식의 차이로 인하여 코드 상에서 여러 오류들이 발생할 수 있습니다.
# 코드
def main():
x = 999; y = 999;
z = 999;
print(x is z) # True
print(x == z) # True
============================
# 인터프리터
>>> x = 999; y = 999;
>>> z = 999;
>>> print(x is z)
False
>>> print(x == z)
True
============================
>>> id(x)
2348159295088
>>> id(y)
2348159295088
>>> id(z)
2348159295152
첫번째 main 함수에서 변수 x, y, z를 할당하고 is
와 ==
를 사용하여 비교하였습니다. 두 결과 모두 True
로 x와 z변수가 같은 값, 같은 메모리 주소를 가지고 있다는 결과를 출력하였습니다.
하지만 바로 아래에 인터프리터에서 실행한 결과는 다른 결과를 보여주고 있습니다. 마찬가지로 x, y, z 변수에 값을 할당하고 is
와 ==
를 사용하여 비교하였습니다. 하지만 is문
에서는 False
, ==비교문
에서는 True
의 값을 반환하였습니다.
이와 같이 서로 다른 결과가 나온 이유는 is
와 ==
의 비교방식의 차이와 최적화 때문입니다. 코드에서는 x, y, z 변수가 모두 한 번에 최적화되어 하나의 메모리 주소를 가리키게 됩니다. 하지만 인터프리터의 경우 줄 단위로 최적화되기 때문에 x, y는 같은 메모리주소를 z는 다른 메모리 주소를 가리키게 되는 것입니다.
따라서 객체의 주소값을 사용하여 객체의 동일성을 검증하는 is
비교에서는 서로 다르다는 결과가 출력되지만, 변수의 값을 비교하는 ==
비교에서는 같다는 결과가 나온것입니다. 즉 최적화의 여부에 따라서 코드가 의도한 결과와는 다르게 동작할 수 있는 것입니다. 따라서 비교문을 사용할 때는 동일성을 검증할 것인지, 동등성을 검증할 것인지를 잘 파악하여 적절한 문법을 사용해야 합니다.