__eq_는 Python에서 어떻게 처리되고 어떤 순서로 처리됩니까?
파이썬은 비교 연산자의 왼쪽/오른쪽 버전을 제공하지 않기 때문에 어떤 함수를 호출할지 어떻게 결정합니까?
class A(object):
def __eq__(self, other):
print "A __eq__ called"
return self.value == other
class B(object):
def __eq__(self, other):
print "B __eq__ called"
return self.value == other
>>> a = A()
>>> a.value = 3
>>> b = B()
>>> b.value = 4
>>> a == b
"A __eq__ called"
"B __eq__ called"
False
이것은 둘 다를 부르는 것처럼 보입니다.__eq__
기능들.
저는 공식 결정 트리를 찾고 있습니다.
그a == b
식호를 호출합니다.A.__eq__
그것이 존재하기 때문에코드는 다음을 포함합니다.self.value == other
int에, 은 int를 호출하려고 .B.__eq__
자신을 int와 비교하는 방법을 알고 있는지 알아보기 위해.
비교 중인 값을 표시하도록 코드를 수정하는 경우:
class A(object):
def __eq__(self, other):
print("A __eq__ called: %r == %r ?" % (self, other))
return self.value == other
class B(object):
def __eq__(self, other):
print("B __eq__ called: %r == %r ?" % (self, other))
return self.value == other
a = A()
a.value = 3
b = B()
b.value = 4
a == b
다음과 같이 출력됩니다.
A __eq__ called: <__main__.A object at 0x013BA070> == <__main__.B object at 0x013BA090> ?
B __eq__ called: <__main__.B object at 0x013BA090> == 3 ?
가 Python2를 볼 때.x에서 다음을 확인할 때a == b
다음과 같은 시도를 합니다.
- 한다면
type(b)
이고, 새운스수업고이의타일로,,,type(b)
의 하위 클래스입니다.type(a)
,그리고.type(b)
오버라이드했습니다.__eq__
그렇다면 결과는b.__eq__(a)
. - 한다면
type(a)
오버라이드했습니다.__eq__
(계속)type(a).__eq__
그렇지 않은object.__eq__
는 , , 입니다.a.__eq__(b)
. - 한다면
type(b)
오버라이드했습니다.__eq__
그렇다면 결과는b.__eq__(a)
. - 되지 않을 , 은 위의내모해않는경우은지, Python반복합다니프를로스세찾는음을다용이를 합니다.
__cmp__
그것이 존재한다면, 이 반환된다면, 그 객체들은 같습니다.zero
. - 은 Python을 최종예고객라고 .
object.__eq__(a, b)
,어느 것이True
만약에a
그리고.b
동일한 개체입니다.
특수한 방법 중 하나라도 반환되는 경우NotImplemented
Python은 메서드가 존재하지 않는 것처럼 동작합니다.
를 주의 깊게 : 것도 그렇지 않다면.a
도 아니다b
==
,그리고나서a == b
는 와동합다니와 .a is b
.
출처: https://eev.ee/blog/2012/03/24/python-faq-equality/
이 알고리즘에 대한 Python 3 변경/업데이트
어떻게 있다.
__eq__
Python에서 처리되며 어떤 순서로 처리됩니까?a == b
그런 것은 아닙니다.a == b
출호를 합니다.a.__eq__(b)
또는type(a).__eq__(a, b)
.
분명히 평가 순서는 다음과 같습니다.
- 한다면
b
은 의유동은의엄하클아다래니입위스격의 엄격한 클래스유형이a
의 유형과 유형이 있습니다.__eq__
합니다. - 그렇지 않으면, 만약
a
가지다__eq__
그것을 참조하십시오. - 아니면, 우리가 B에게 전화하지 않았는지 보세요.
__eq__
, , 리고그그가있고, 비실그전돌다려니줍. - 동일성에 합니다. 동일성에 대한 비교는 으로그에, 정막대비하, 체비를하라같, 를라교은교한과 같은 입니다.
is
.
메소드가 반환되는 경우 비교가 구현되지 않는지 여부를 알고 있습니다.NotImplemented
.
에는 (파이썬 2)가.__cmp__
찾았지만 Python 3에서 더 이상 사용되지 않고 제거된 메서드입니다.)
B를 하위 클래스 A로 지정하여 첫 번째 검사의 동작을 직접 테스트해 보겠습니다. A는 이 카운트에서 허용된 답변이 잘못되었음을 나타냅니다.
class A:
value = 3
def __eq__(self, other):
print('A __eq__ called')
return self.value == other.value
class B(A):
value = 4
def __eq__(self, other):
print('B __eq__ called')
return self.value == other.value
a, b = A(), B()
a == b
은 오직 만 합니다.B __eq__ called
False
.
참고로 다음과 같은 질문에서 작은 오류도 수정합니다.self.value
됩니다.other
에 other.value
에서, 는 두 의 물체이비교우리, 물는두개얻다습니체를의서에▁(다이)를 얻습니다.self
그리고.other
를 하지 않기 유형의 입니다. (은 다른 수 ), 우리는 그것들이 한지 알아야 .), 여서는그유검형동수일유며로으반일않이형적동있합때문다수음알니일야여한아다한기를부지를러나유에이형기사행하지를▁),그▁usually동다합일▁of-▁since),니▁(▁we야),but▁are▁if▁are한여▁the알▁here여▁and지아▁type▁we▁they▁equal▁doing▁samechecking▁no▁type▁types(▁need부를기▁they),음있▁to그들이 동등한지 아닌지에 대한 우리의 측정은 다음을 확인하는 것입니다.value
속성. 두 개체 모두에서 수행해야 합니다.
이 완전한 알고리즘을 어떻게 알 수 있을까요?
여기에 있는 다른 답변들은 불완전하고 구식인 것 같습니다. 그래서 저는 정보를 업데이트하고 여러분이 어떻게 이것을 직접 찾을 수 있는지 보여드리겠습니다.
이것은 C 레벨에서 처리됩니다.
우리는 여기서 두 개의 다른 코드 비트 - 기본값을 살펴볼 필요가 있습니다.__eq__
에급▁의 객체에 대해.object
그리고 코드를 찾아 전화를 거는 것입니다.__eq__
입니다.__eq__
또는 사용자 지정된 것.
체__eq__
중 ㅠㅠ__eq__
관련 Capi 문서에 있는 것은 우리에게 보여줍니다.__eq__
에 의해 처리됨 - 의"object"
의 형식 정의는 다음에서 정의됩니다.object_richcompare
위해서case Py_EQ:
.
case Py_EQ:
/* Return NotImplemented instead of False, so if two
objects are compared, both get a chance at the
comparison. See issue #1393. */
res = (self == other) ? Py_True : Py_NotImplemented;
Py_INCREF(res);
break;
그래서 여기, 만약에.self == other
우리는 돌아옵니다.True
그렇지 않으면 반환합니다.NotImplemented
물건.자체적으로 구현하지 않는 모든 하위 클래스의 기본 동작입니다.__eq__
방법.
어떻게.__eq__
불립니다.
그런 다음 C API 문서인 PyObject_RichCompare 함수를 찾습니다. 이 함수는 다음을 호출합니다.do_richcompare
.
그러면 우리는 그것을 봅니다.tp_richcompare
, 다을위를 위해 생성됨"object"
C 정의는 다음과 같이 호출됩니다.do_richcompare
좀 더 자세히 살펴보도록 하겠습니다.
이 기능의 첫 번째 점검은 비교 중인 물체의 상태에 대한 것입니다.
- 동일한 유형은 아니지만,
- 두 번째 유형은 첫 번째 유형의 하위 클래스입니다.
- 두 번째 유형은 다음과 같습니다.
__eq__
변수,
그런 다음 인수가 스왑된 다른 메소드를 호출하여 구현된 경우 값을 반환합니다.만약 그 방법이 실행되지 않는다면, 우리는 계속...
if (!Py_IS_TYPE(v, Py_TYPE(w)) &&
PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v)) &&
(f = Py_TYPE(w)->tp_richcompare) != NULL) {
checked_reverse_op = 1;
res = (*f)(w, v, _Py_SwappedOp[op]);
if (res != Py_NotImplemented)
return res;
Py_DECREF(res);
다음에는 우리가 찾을 수 있는지 살펴봅니다.__eq__
메서드를 첫 번째 유형에서 호출합니다.결과가 구현되지 않은 경우, 즉 구현된 경우에는 반환합니다.
if ((f = Py_TYPE(v)->tp_richcompare) != NULL) {
res = (*f)(v, w, op);
if (res != Py_NotImplemented)
return res;
Py_DECREF(res);
그렇지 않으면 다른 유형의 방법을 시도하지 않고 사용해 보고 비교가 구현되면 반환합니다.
if (!checked_reverse_op && (f = Py_TYPE(w)->tp_richcompare) != NULL) {
res = (*f)(w, v, _Py_SwappedOp[op]);
if (res != Py_NotImplemented)
return res;
Py_DECREF(res);
}
마지막으로, 우리는 어느 한 사람의 유형에 대해서도 구현되지 않은 경우에 대비합니다.
합니다. - 은 개의은체즉 ID, 동위있개여동부확일다지인합니를체인치일는한과 한 입니다. 이는 다음과 같은 검사입니다.self is other
:
/* If neither object implements it, provide a sensible default
for == and !=, but raise an exception for ordering. */
switch (op) {
case Py_EQ:
res = (v == w) ? Py_True : Py_False;
break;
결론
비교에서, 우리는 비교의 하위 클래스 구현을 먼저 존중합니다.
그런 다음 첫 번째 개체의 구현과 비교하고, 호출되지 않은 두 번째 개체의 구현과 비교합니다.
마지막으로 동일성에 대한 비교를 위해 동일성에 대한 테스트를 사용합니다.
언급URL : https://stackoverflow.com/questions/3588776/how-is-eq-handled-in-python-and-in-what-order
'programing' 카테고리의 다른 글
mgo가 삽입된 문서의 ID를 반환하지 않는 이유는 무엇입니까? (0) | 2023.07.17 |
---|---|
"작업 친화적 동기화 컨텍스트 사용"의 의미는 무엇입니까? (0) | 2023.07.17 |
Excel 추가 기능 - 클릭 한 번 - VSTOInstaller.exe.config 파일, 무엇입니까? (0) | 2023.07.17 |
aspx 보기에서 '사용' 문을 사용할 수 있습니까?(ASP.NET MVC) (0) | 2023.07.17 |
TS1128: 선언 또는 문이 필요합니다(파일 끝). (0) | 2023.07.17 |