Hướng dẫn python override compare method - ghi đè lên phương pháp so sánh python

Giả sử bạn có một lớp đơn giản như A dưới đây. Các phương pháp so sánh đều gần như giống nhau ngoại trừ chính so sánh. Có một lối tắt nào xung quanh việc khai báo sáu phương pháp trong một phương pháp sao cho tất cả các so sánh được hỗ trợ, một cái gì đó như

>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
0?

Tôi hỏi chủ yếu vì

>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
0 có vẻ như Pythonic đối với tôi và tôi ngạc nhiên khi việc tìm kiếm của tôi không tìm thấy một tuyến đường như vậy.

class A:
    def __init__[self, number: float, metadata: str]:
        self.number = number
        self.metadata = metadata

    def __lt__[self, other]:
        return self.number < other.number

    def __le__[self, other]:
        return self.number  other.number

    def __ge__[self, other]:
        return self.number >= other.number

    def __eq__[self, other]:
        return self.number == other.number

    def __ne__[self, other]:
        return self.number != other.number


class B:
    def __init__[self, number: float, metadata: str]:
        self.number = number
        self.metadata = metadata

    def __compare__[self, other, comparison]:
        return self.number.__compare__[other.number, comparison]

Trong Python 3, tham số
from functools import total_ordering

@total_ordering
class Person[object]:

    def __init__[self, firstname, lastname]:
        self.first = firstname
        self.last = lastname

    def __eq__[self, other]:
        return [[self.last, self.first] == [other.last, other.first]]

    def __ne__[self, other]:
        return not [self == other]

    def __lt__[self, other]:
        return [[self.last, self.first]  y] - [x >> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]

Python 3 là nghiêm ngặt khi so sánh các đối tượng của các loại khác nhau. Nó cũng giảm so sánh dựa trên CMP và phân loại có lợi cho các so sánh phong phú và phân loại chính, các lựa chọn thay thế hiện đại đã có sẵn ít nhất kể từ Python 2.4. Chi tiết và chiến lược chuyển tiếp theo.

Các loại không thể đặt hàng

Cách tiếp cận nghiêm ngặt để so sánh trong Python 3 khiến thường không thể so sánh các loại đối tượng khác nhau.

  • FIXER: Không có: None
  • Tỷ lệ lưu hành: chung

Ví dụ, trong Python 2, so sánh

>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
2 và
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
3 hoạt động [với kết quả không thể đoán trước được trong quá trình triển khai Python]:

Nhưng trong Python 3, nó thất bại với một thông báo lỗi được mô tả tốt:

Sự thay đổi thường thể hiện trong danh sách sắp xếp: trong Python 3, danh sách với các mục thuộc loại khác nhau thường không thể sắp xếp.

Nếu bạn cần sắp xếp các danh sách không đồng nhất hoặc so sánh các loại đối tượng khác nhau, hãy thực hiện một chức năng chính để mô tả đầy đủ cách các loại khác nhau nên được đặt hàng.

So sánh phong phúPhương pháp đặc biệt
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
4 không còn được tôn vinh trong Python 3.
Trong Python 2,
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
5 đã thực hiện so sánh giữa hai đối tượng, trả về giá trị âm nếu
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
6, dương nếu
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
7 và không nếu chúng bằng nhau.
Cách tiếp cận này thể hiện kết quả so sánh là phổ biến trong các ngôn ngữ kiểu C. Nhưng, sớm trong sự phát triển của Python 2, rõ ràng là chỉ cho phép ba trường hợp cho thứ tự tương đối của các đối tượng là quá hạn chế.
Điều này dẫn đến việc giới thiệu các phương pháp so sánh phong phú, gán một phương pháp đặc biệt cho mỗi toán tử:Nhà điều hành
Phương pháp==
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
8
! =
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
9

Để tránh rắc rối trong việc cung cấp tất cả sáu chức năng, bạn có thể thực hiện

>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
8,
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
9 và chỉ một trong các nhà khai thác đặt hàng và sử dụng trình trang trí
from functools import total_ordering

@total_ordering
class Person[object]:

    def __init__[self, firstname, lastname]:
        self.first = firstname
        self.last = lastname

    def __eq__[self, other]:
        return [[self.last, self.first] == [other.last, other.first]]

    def __ne__[self, other]:
        return not [self == other]

    def __lt__[self, other]:
        return [[self.last, self.first] >> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
4 được thực hiện:

class Person[object]:
    def __init__[self, firstname, lastname]:
         self.first = firstname
         self.last = lastname

    def __cmp__[self, other]:
        return cmp[[self.last, self.first], [other.last, other.first]]

    def __repr__[self]:
        return "%s %s" % [self.first, self.last]

Với

from functools import total_ordering

@total_ordering
class Person[object]:

    def __init__[self, firstname, lastname]:
        self.first = firstname
        self.last = lastname

    def __eq__[self, other]:
        return [[self.last, self.first] == [other.last, other.first]]

    def __ne__[self, other]:
        return not [self == other]

    def __lt__[self, other]:
        return [[self.last, self.first]  y] - [x >> actors = [Person['Eric', 'Idle'],
...           Person['John', 'Cleese'],
...           Person['Michael', 'Palin'],
...           Person['Terry', 'Gilliam'],
...           Person['Terry', 'Jones']]
...

Biểu thức được sử dụng không đơn giản, vì vậy nếu bạn cần chức năng, chúng tôi khuyên bạn nên thêm chức năng đầy đủ, được ghi lại vào thư viện tiện ích dự án của bạn.

>>> def cmp_last_name[a, b]:
...     """ Compare names by last name"""
...     return cmp[a.last, b.last]
...
>>> sorted[actors, cmp=cmp_last_name]
['John Cleese', 'Terry Gilliam', 'Eric Idle', 'Terry Jones', 'Michael Palin']

Đối số

from functools import total_ordering

@total_ordering
class Person[object]:

    def __init__[self, firstname, lastname]:
        self.first = firstname
        self.last = lastname

    def __eq__[self, other]:
        return [[self.last, self.first] == [other.last, other.first]]

    def __ne__[self, other]:
        return not [self == other]

    def __lt__[self, other]:
        return [[self.last, self.first] >> def keyfunction[item]:
...     """Key for comparison by last name"""
...     return item.last
...
>>> sorted[actors, key=keyfunction]
['John Cleese', 'Terry Gilliam', 'Eric Idle', 'Terry Jones', 'Michael Palin']

Trong các hàm Python 2,

from functools import total_ordering

@total_ordering
class Person[object]:

    def __init__[self, firstname, lastname]:
        self.first = firstname
        self.last = lastname

    def __eq__[self, other]:
        return [[self.last, self.first] == [other.last, other.first]]

    def __ne__[self, other]:
        return not [self == other]

    def __lt__[self, other]:
        return [[self.last, self.first] 

Bài Viết Liên Quan

Chủ Đề