Home [Python] ==와 is의 차이점
Post
Cancel

[Python] ==와 is의 차이점

TL;DR 📌

  1. 파이썬에서 변수(variable)는 객체(attach)에 부여(attach, bind)된 라벨(label)일 뿐이며, 값을 담고 있는 상자(box)가 아니다.
  2. ==equality를 비교하는 연산자이고, isidentity를 비교하는 연산자이다.


변수(Variable)

파이썬의 == 연산자와 is 연산자의 차이점에 대해 알기 위해서는 먼저 변수가 무엇인지 알아야 한다.

파이썬에서 변수(variable)란 어떠한 값을 담고 있는 상자(box)가 아니라 객체(object)에 부여(attach, bind)된 라벨(label)에 불과하며, 객체는 변수에 의해 참조(referenced)된다.

즉, 다음과 같이 ba를 할당하는 식(assignment)은 상자 a의 내용을 상자 b로 복사하는 것이 아닌, 라벨 a를 가지는 객체에 라벨 b를 부여(= attach, bind)하는 것이다.

1
b = a  # 가리키는 객체가 list라면, 변수 a와 b는 모두 동일한 list에 대한 참조를 가진다.


이와 같은 assignment 상황에서는 우변에서 생성 또는 참조된 객체좌변에 위치한 라벨을 부여하게 되므로, 우변의 객체는 라벨이 부여되기 이전에 존재해야 한다. 따라서 다음의 코드에서는 우변 코드가 평가되기 전에 예외가 발생하므로 변수 y가 생성되지 않는다.


정리하면, 변수에 할당하는 식에서 우변과 좌변은 각각 다음과 같이 정리할 수 있다.

PositionMeaningDescription
lefthand sidevariablebound to the object, like a label
righthand sideobjectwhere the object is created or retrieved


== vs. is

파이썬에서 비교를 위해서 사용하는 연산자에는 ==is가 있다. 두 연산자의 차이점은 무엇일까?

바로 우리가 흔히 을 비교할 때 사용하는 ==equality를 비교하는 연산자이고, isidentity를 비교하는 연산자라는 점이다.

표를 통해 자세히 비교하면 다음과 같다.

id() 함수: CPython의 경우, 객체의 메모리 주소를 유일한 정수 값으로 반환한다.

OperatorComparison CriterionDescriptionSpeed
==value(equality)해당 클래스의 __eq__ 메서드의 구현대로 동작
(즉, a == ba.__eq__(b))
⬇️
isidentity- id() 함수를 이용하여 구한 객체의 ID 비교
- ID는 객체의 생애주기 동안 변하지 않음
⬆️


is 연산자

  1. alias 관계인 두 변수는 같은 객체에 부여되므로, is로 비교하면 True를 반환한다.

    alias 관계란, 둘 이상의 참조가 하나의 객체에 부여될 때 참조들 간의 관계를 뜻한다.

    1
    2
    3
    
     charles = {"name": "Charles L. Dodgson", "born": 1832}
     lewis = charles # -- lewis는 charles의 alias
     lewis is charlse # -- True
    
  2. 변수를 싱글톤(singleton) 객체와 비교하는 경우, is를 사용해야 한다.

    싱글톤 객체의 예시로는 None, sentinel objects 등이 있다.


is== 보다 빠르다!

is 연산자의 동작이 단순히 정수로 이루어진 두 ID를 비교하는 것에 불과하기 때문이다.

반면, == 연산자a.__eq__(b)의 syntactic sugar로서 동일하게 동작한다. object로부터 상속받은 __eq__ 메서드는 is와 마찬가지로 두 객체의 ID를 비교하지만, 대다수의 built-in 타입에서는 __eq__ 메서드를 다른 의미있는 구현으로 오버라이드(override)하기 때문에 객체의 값을 고려하게 된다. 따라서 큰 collection 타입이나 중첩된 구조를 비교할 때 많은 연산을 필요로 한다.


오버로딩(overloading) vs. 오버라이딩(overriding)

  • 오버로딩: 여러 함수가 같은 이름을 가지고 있으나 매개변수의 타입 및 개수가 다른 것
  • 오버라이딩: 상위 클래스에서 정의한 메서드를 하위 클래스에서 재정의하는 것


사용자 정의 클래스 관련 주의사항

사용자 정의 클래스에서는 __eq__ method를 override하여 ==가 instance에서 의미하는 바를 결정할 수 있다.

하지만 __eq__ method를 override 하지 않는다면 object에서 상속 받은 __eq__ method(= comparing object IDs)가 실행되므로, 모든 instances가 다르다고 판단될 수 있다.


References

  • “Fluent Python (2nd Edition)”, Ch06. Object References, Mutability, and Recycling
This post is licensed under CC BY 4.0 by the author.

[Python] First-Class Object, Higher-Order Function, 그리고 함수형 프로그래밍

[Python] 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)