ฉันกำลังเขียนคำตอบที่อัปเดตสำหรับ 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เรารู้ว่าถ้าเปรียบเทียบไม่ได้ดำเนินการหากผลตอบแทนที่วิธีการ
(ใน Python 2 มีไฟล์ __cmp__เมธอดที่ถูกมองหา แต่ถูกเลิกใช้งานและลบออกใน Python 3)
ลองทดสอบพฤติกรรมของเช็คแรกด้วยตัวเราเองโดยปล่อยให้ B subclass 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เท่านั้น
เราจะรู้อัลกอริทึมทั้งหมดนี้ได้อย่างไร?
คำตอบอื่น ๆ ที่นี่ดูเหมือนจะไม่สมบูรณ์และล้าสมัยดังนั้นฉันจะอัปเดตข้อมูลและแสดงให้คุณเห็นว่าคุณจะค้นหาสิ่งนี้ด้วยตัวคุณเองได้อย่างไร
สิ่งนี้ได้รับการจัดการที่ระดับ C
เราต้องดูรหัสสองบิตที่แตกต่างกันที่นี่ - ค่าเริ่มต้น__eq__สำหรับวัตถุของคลาสobjectและรหัสที่ค้นหาและเรียกใช้__eq__เมธอดโดยไม่คำนึงว่าจะใช้ค่าเริ่มต้นหรือไม่__eq__หรือแบบกำหนดเอง
ค่าเริ่มต้น __eq__
มอง__eq__ขึ้นมาในที่เกี่ยวข้องเอกสาร C APIแสดงให้เราเห็นว่า__eq__จะถูกจัดการโดยtp_richcompare- ซึ่งใน"object"การกำหนดประเภทในการcpython/Objects/typeobject.cกำหนดไว้ในสำหรับobject_richcomparecase 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 
        res = (self == other) ? Py_True : Py_NotImplemented;
        Py_INCREF(res);
        break;
ที่นี่ถ้าself == otherเรากลับมาTrueก็จะส่งคืนNotImplementedวัตถุ นี่เป็นลักษณะการทำงานเริ่มต้นสำหรับคลาสย่อยของอ็อบเจ็กต์ที่ไม่ได้ใช้__eq__วิธีการของตัวเอง
วิธีการ__eq__ได้รับเรียกว่า
จากนั้นเราจะพบเอกสาร C API ที่PyObject_RichComparedo_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);
    }
สุดท้ายเราได้รับทางเลือกในกรณีที่ไม่ได้ใช้กับประเภทใดประเภทหนึ่ง
ทางเลือกจะตรวจสอบข้อมูลประจำตัวของวัตถุนั่นคือว่าเป็นวัตถุเดียวกันที่ตำแหน่งเดียวกันในหน่วยความจำหรือไม่ซึ่งเป็นการตรวจสอบเช่นเดียวกับ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;
สรุป
ในการเปรียบเทียบเราเคารพการใช้คลาสย่อยของการเปรียบเทียบก่อน
จากนั้นเราลองเปรียบเทียบกับการนำไปใช้งานของออบเจ็กต์แรกจากนั้นกับสิ่งที่สองถ้ามันไม่ถูกเรียก
ในที่สุดเราก็ใช้การทดสอบเอกลักษณ์เพื่อเปรียบเทียบความเท่าเทียมกัน