답변:
==
입니다 평등 테스트 . 오른쪽과 왼쪽이 동일한 물체인지 여부를 확인합니다 ( __eq__
또는 __cmp__
방법 에 따라 ).
is
입니다 확인 시험은 . 오른쪽과 왼쪽이 동일한 객체인지 확인합니다. 메소드 호출이 수행되지 않으며 객체는 is
작업에 영향을 줄 수 없습니다 .
척하려는 객체에 대해 신경 쓰지 않거나 와 비교할 때 객체가 깨지는 것을 방지하려는 경우와 같이 싱글 톤에 is
(및 is not
)를 사용 None
합니다 .None
None
None
메소드가 거의없고 속성이 거의 없습니다. __eq__
테스트에서 메소드 또는 속성을 예상 한 경우 중단 될 수 있습니다. def __eq__( self, other ): return self.size == other.size
. 예를 들어이면 other
발생합니다 None
.
is
과 같습니다 . Python 은 Java와 같습니다 ==
. 파이썬 ==
은 자바와 같습니다 .equals()
. 물론 이것은 Java를 아는 경우에만 도움이됩니다.
is
처럼 ===
(매우 같음), 반대로 is not
같다 !==
(정확하게 동일하지 않음).
is not
단일 연산자 입니까 , 아니면 is
내부적으로 결과를 부정 not foo is bar
합니까?
먼저 몇 가지 용어를 살펴 보겠습니다. 질문에 대한 답변을 원하면 "질문 답변"으로 스크롤하십시오.
객체 식별 : 객체를 생성 할 때 변수에 할당 할 수 있습니다. 그런 다음 다른 변수에 할당 할 수도 있습니다. 그리고 또 다른.
>>> button = Button()
>>> cancel = button
>>> close = button
>>> dismiss = button
>>> print(cancel is close)
True
이 경우 cancel
, close
및 dismiss
모든 메모리에 동일한 객체를 참조. 하나의 Button
오브젝트 만 작성 했으며 세 개의 변수 모두이 하나의 오브젝트를 참조합니다. 우리는 그런 말을 cancel
, close
그리고 dismiss
모두를 참조 동일 객체; 즉, 그들은 하나의 단일 객체를 참조합니다.
객체 평등 : 두 객체를 비교할 때 일반적으로 메모리에서 정확히 동일한 객체를 참조하는 것은 중요하지 않습니다 . 객체 평등을 사용하면 두 객체를 비교하는 방법에 대한 고유 한 규칙을 정의 할 수 있습니다. 당신이 쓸 때 if a == b:
, 당신은 본질적으로 말하는 것 if a.__eq__(b):
입니다. 이를 통해 __eq__
메소드 를 정의 a
하여 자신 만의 비교 논리를 사용할 수 있습니다.
근거 : 두 개체의 데이터는 동일하지만 동일하지 않습니다. (메모리에서 동일한 객체가 아닙니다.) 예 : 문자열
>>> greeting = "It's a beautiful day in the neighbourhood."
>>> a = unicode(greeting)
>>> b = unicode(greeting)
>>> a is b
False
>>> a == b
True
참고 : 파이썬은 메모리에 새로운 문자열을 만들지 않고 일반 문자열을 재사용 할만 큼 똑똑하기 때문에 여기에서 유니 코드 문자열을 사용합니다.
자, 내가이 유니 코드 문자열을 가지고 a
와 b
. 그들은 동일한 내용을 가지고 있지만 메모리에서 동일한 객체가 아닙니다. 그러나 우리가 그것들을 비교할 때, 그들이 동등하게 비교되기를 원합니다. 여기서 일어나는 일은 유니 코드 객체가 __eq__
메소드 를 구현했다는 것입니다.
class unicode(object):
# ...
def __eq__(self, other):
if len(self) != len(other):
return False
for i, j in zip(self, other):
if i != j:
return False
return True
참고 : __eq__
on unicode
은 이것보다 확실히 효율적으로 구현됩니다.
이론적 근거 : 두 개체의 데이터는 다르지만 일부 키 데이터가 동일한 경우 동일한 개체로 간주됩니다. 예 : 대부분의 모델 데이터 유형
>>> import datetime
>>> a = Monitor()
>>> a.make = "Dell"
>>> a.model = "E770s"
>>> a.owner = "Bob Jones"
>>> a.warranty_expiration = datetime.date(2030, 12, 31)
>>> b = Monitor()
>>> b.make = "Dell"
>>> b.model = "E770s"
>>> b.owner = "Sam Johnson"
>>> b.warranty_expiration = datetime.date(2005, 8, 22)
>>> a is b
False
>>> a == b
True
자, 내가이 개 델 모니터를 가지고 a
와 b
. 그들은 같은 제조사와 모델을 가지고 있습니다. 그러나 메모리에 동일한 데이터가 없거나 동일한 오브젝트가 없습니다. 그러나 우리가 그것들을 비교할 때, 그들이 동등하게 비교되기를 원합니다. 여기서 일어나는 일은 Monitor 객체가 __eq__
메소드를 구현했다는 것입니다.
class Monitor(object):
# ...
def __eq__(self, other):
return self.make == other.make and self.model == other.model
와 비교할 때는 항상를 None
사용하십시오 is not
. 파이썬에는 싱글 톤이 없습니다. 메모리에는 인스턴스가 하나뿐입니다.
아이덴티티 를 비교하면 매우 빠르게 수행 할 수 있습니다. 파이썬은 당신이 말하는 객체가 전역 None 객체와 동일한 메모리 주소를 가지고 있는지 확인합니다-두 숫자를 매우 빠르게 비교합니다.
평등 을 비교함으로써 파이썬은 객체에 __eq__
메소드 가 있는지 찾아야합니다 . 그렇지 않은 경우, __eq__
메소드를 찾는 각 수퍼 클래스를 검사합니다 . 하나를 찾으면 파이썬은 그것을 호출합니다. 이 __eq__
방법은 속도가 느리고 다른 객체가 인 경우 즉시 반환하지 않는 경우 특히 나쁩니다 None
.
구현하지 않았습니까 __eq__
? 그러면 파이썬은 아마도 __eq__
메소드를 찾아서 object
대신 사용할 것입니다-어쨌든 객체 신원을 확인합니다.
파이썬에서 대부분의 다른 것들을 비교할 때는을 사용 !=
합니다.
다음을 고려하세요:
class Bad(object):
def __eq__(self, other):
return True
c = Bad()
c is None # False, equivalent to id(c) == id(None)
c == None # True, equivalent to c.__eq__(None)
None
은 싱글 톤이므로 항등 비교는 항상 작동하는 반면 객체는를 통해 등가 비교를 가짜로 만들 수 있습니다 .__eq__()
.
None
언급하지 않았지만 None
다른 유형에 대해 평등을 구현하는 데 따른 부작용으로 잘못된 행동 이 발생할 수 있습니다. 정확성에 영향을주기 때문에 보안에 큰 영향을 미치지는 않습니다.
>>> ()는 () 진실 >>> 1은 1입니다 진실 >>> (1,) == (1,) 진실 >>> (1,)은 (1,) 그릇된 >>> a = (1,) >>> b = a >>> a는 b입니다 진실
일부 객체는 싱글 톤이므로 이것 is
과 동일합니다 ==
. 대부분은 아닙니다.
()
그리고 1
본질적으로 싱글 없습니다.
-NSMALLNEGINTS <= n <= NSMALLPOSINTS
) 및 빈 튜플 은 싱글 톤입니다. 실제로 문서화되거나 보장되지는 않지만 변경되지는 않습니다.