답변:
이것은 __dunder__
메소드가 동등한 연산자를 대체하기에 적절하지 않은 경우가 많으므로 직접 사용해서는 안되는 이유에 대한 훌륭한 예입니다 . 당신은 사용해야 ==
평등 비교 대신 연산자를, 또는이 특별한 경우에 검사 할 때 None
사용 is
(자세한 내용은 답변 아래로 이동).
너는 해냈어
None.__eq__('a')
# NotImplemented
NotImplemented
비교되는 유형이 다르기 때문에 어느 것이 반환 됩니다. 유형이 다른 두 객체가 이러한 방식으로 비교되는 또 다른 예를 고려하십시오 (예 : 1
및) 'a'
. 수행하는 (1).__eq__('a')
것도 올바르지 않으며을 반환 NotImplemented
합니다. 이 두 값을 동등하게 비교하는 올바른 방법은
1 == 'a'
# False
여기서 일어나는 일은
(1).__eq__('a')
, 어떤 반환을 시도합니다 NotImplemented
. 이는 작업이 지원되지 않음을 나타냅니다.'a'.__eq__(1)
가 호출되어 동일한을 반환합니다 NotImplemented
. 그래서,False
반환됩니다.이 방법을 설명하기 위해 일부 사용자 정의 클래스를 사용하는 멋진 MCVE가 있습니다.
class A:
def __eq__(self, other):
print('A.__eq__')
return NotImplemented
class B:
def __eq__(self, other):
print('B.__eq__')
return NotImplemented
class C:
def __eq__(self, other):
print('C.__eq__')
return True
a = A()
b = B()
c = C()
print(a == b)
# A.__eq__
# B.__eq__
# False
print(a == c)
# A.__eq__
# C.__eq__
# True
print(c == a)
# C.__eq__
# True
물론, 왜 작업이 true를 반환 하는지 는 설명하지 않습니다 . 이것은 NotImplemented
실제로 진실한 가치 이기 때문 입니다.
bool(None.__eq__("a"))
# True
같은
bool(NotImplemented)
# True
어떤 값이 진실되고 허위로 간주되는지에 대한 자세한 내용 은 이 답변 뿐만 아니라 진실 값 테스트 에 대한 문서 섹션을 참조하십시오 . 그것은 여기에 주목할 필요가있다 truthy이지만, 그것은 다른 이야기가 클래스가 정의했다이었을 것 또는 반환 된 방법 또는 각각을.NotImplemented
__bool__
__len__
False
0
==
연산자 와 동등한 기능을 원하면 다음을 사용하십시오 operator.eq
.
import operator
operator.eq(1, 'a')
# False
그러나 앞에서 언급했듯이이 특정 시나리오 에서는 확인하려는 다음을 None
사용하십시오 is
.
var = 'a'
var is None
# False
var2 = None
var2 is None
# True
이것과 동등한 기능을 사용하고 있습니다 operator.is_
:
operator.is_(var2, None)
# True
None
는 특별한 객체이며, 어떤 시점에서도 메모리에 1 개의 버전 만 존재합니다. IOW는 NoneType
클래스 의 유일한 싱글 톤입니다 (그러나 동일한 객체는 여러 참조를 가질 수 있습니다). PEP8 가이드 라인 이 명시합니다
싱글 톤과의 비교
None
는 항상 등호 연산자를 사용하지 않고is
또는 로 수행해야합니다is not
.
요약하면, 싱글이 좋아하는 위해 None
를 가진 참조 검사가 is
더 적합, 모두 비록 ==
및 is
잘 작동합니다.
당신이보고있는 결과는
None.__eq__("a") # evaluates to NotImplemented
로 평가되고 NotImplemented
, NotImplemented
진실의 가치는 다음과 같이 문서화됩니다 True
:
https://docs.python.org/3/library/constants.html
(예를 들면 진 특별한 방법에 의해 반환되는 특수한 값
__eq__()
,__lt__()
,__add__()
,__rsub__()
, 등)의 동작은 다른 유형에 대하여 구현되지 않는다는 것을 표시하는 단계; 인플레 이스 (in-place) 진 특별한 방법 (예에 의해 반환 될 수 있습니다__imul__()
,__iand__()
같은 목적 등). 진실의 가치는 사실입니다.
을 __eq()__
사용하지 않고 수동으로 메소드 를 호출하는 경우 ==
, 리턴 될 가능성 NotImplemented
과 실제 값이 참인지 를 처리 할 준비가되어 있어야 합니다.
예를 반환합니다 NotImplemented
.
>>> None.__eq__('a')
NotImplemented
>>>
그러나 이것을 보면 :
>>> bool(NotImplemented)
True
>>>
NotImplemented
truthy 값이 실제로는 반환 이유의 때문에 b
, 아무것도 True
이다 통과 할 것이다, 아무것도 False
하지 않을 것입니다.
당신이 그것이 있는지 확인해야 True
하므로 더 의심스러워하십시오.
>>> NotImplemented == True
False
>>>
그래서 당신은 할 것입니다 :
>>> if None.__eq__('a') == True:
print('b')
>>>
보시다시피 아무것도 반환하지 않습니다.