Python에서 ==과 is은 비슷해보이지만 다른 의미를 가지고 있습니다.
결론부터 이야기하면 ==은 객체가 가지고 있는 값 비교이고 is은 객체가 같은지를 비교하는 것입니다.
예를 들어보겠습니다.
str1 = 'test'
str2 = 'test'
print(str1 == str2) # true
print(str1 is str2) # true
str1,str2은 둘다 'test'라는 값을 가지고 있는 str를 참조하고 있고
어쨌던 간에 ==은 값을 비교한다고 했으니 str1 == str2은 true가 맞습니다.
그럼 str1 is str2은 왜 true일까요?
그건 str1와 str2이 값만 같은게 아니라 아예 동일한 str 객체이기 때문입니다.
내장함수 id()를 이용해 주소를 확인해보겠습니다.
str1 = 'test'
str2 = 'test'
print(str1 == str2) # true
print(str1 is str2) # true
print(id(str1)) # 2251936
print(id(str2)) # 2251936
메모리 주소를 나타내는 id()을 이용한 id(str1), id(str2) 두 값이 동일합니다.
위의 경우는 str1, str2 참조하는 객체나 그 객체의 값이 모두 동일해서 그렇습니다.
그럼 원래 이런 것 아니냐 is랑 ==이 무슨 차이냐고 하실 수도 있어 새로운 예를 들어 보겠습니다.
str1 = 'test'
str2 = 'test'
str3 = ''.join(['t','e','s','t'])
print(str1) # 'test'
print(str2) # 'test'
print(str3) # 'test'
print(str1 == str2) # true
print(str1 is str2) # true
print(str1 == str3) # true
print(str1 is str3) # false
str3에 ''.join(['t','e','s','t'])을 이용해 결국 'test라는 str를 참조하게 했습니다.
str1이나 str2이나 그리고 str3 모두 결국 'test'라는 str를 참조하고 있습니다.
그럼 이 셋은 ==, is의 결과가 모두 같다고 생각하실 수도 있는데 그렇지 않습니다.
모두 'test'라는 값을 갖고 있는 것은 맞으나
str1, str2이 가리키는 주소와 str3이 가리키는 주소가 다릅니다.
확인해보겠습니다.
str1 = 'test'
str2 = 'test'
str3 = ''.join(['t','e','s','t'])
print(id(str1)) # 2710688
print(id(str2)) # 2710688
print(id(str3)) # 8021568
str1와 str2은 주소가 같은데 str3만 다릅니다.
그 이유는 Python 메모리 재활용과 연관이 있습니다.
이는 Object Interning으로 이미 생성된 객체를 재사용하는 것입니다.
간단히 말해서 str1라는 변수가 참조하는 'test'를 만들고 나서 따로 이를 저장해두었다가 str2가 또 'test'를 참조하려고 하면 str1에서 썼던 것을 그대로 활용하는 것입니다.
그래서 객체의 값을 비교하나 주소를 비교하나 같은 값을 갖는 것이고
str3은 str1, str2와 다르게 리터럴 방식(ex str3 = 'test')으로 생성하지 않았으므로 기존에 저장된 'test'를 그대로 사용하지 못하고 새로운 주소(8021568)를 할당 받게 되었습니다.
이렇게 Interning을 이용해 객체를 재활용할 수 있도록 Python이 준비해줄 수도 있고
개발자가 직접 intern() 함수를 이용할 수도 있습니다.
(intern 함수는 Python2에서는 기본 내장함수지만 Python3부터는 sys 패키지에 속합니다.)
어찌되었던 정확히 ==과 is가 무엇을 비교하는 연산인지를 이해하는 것이 중요하겠습니다.
'파이썬 > 기초문법' 카테고리의 다른 글
Python Exception 발생시 해당 소스, 라인 출력하기 (0) | 2020.03.03 |
---|---|
Python Map에 대한 이해 (1) | 2020.02.14 |
Relative imports in Python 3 (0) | 2020.02.02 |
Multiprocessing vs. Threading in Python: What Every Data Scientist Needs to Know (0) | 2020.01.30 |
Python NumPy 배열 기초 (0) | 2020.01.24 |
댓글