Hướng dẫn python compare functions - python so sánh các chức năng
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á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. Ví dụ, trong Python 2, so sánh các tác phẩm 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. Phương pháp đặc biệt Trong Python 2, 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)1 đã thực hiện so sánh giữa hai đối tượng, trả về giá trị âm nếu 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)2, dương nếu 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)3 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ử:
Mỗi đối số lấy hai đối số giống như CMP và phải trả về giá trị kết quả (thường là boolean), tăng một ngoại lệ hoặc trả về 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) < (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last)0 để báo hiệu hoạt động không được xác định. Trong Python 3, kiểu so sánh CMP đã bị loại bỏ. Tất cả các đối tượng được triển khai 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) < (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last)1 phải được cập nhật để thực hiện tất cả các phương thức phong phú thay thế. . Để tránh sự rắc rối của việc cung cấp tất cả sáu chức năng, bạn có thể 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)4, 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)5 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) < (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last)6 để điền vào phần còn lại. Lưu ý rằng người trang trí không có sẵn trong Python 2.6. Nếu bạn cần hỗ trợ phiên bản đó, bạn sẽ cần cung cấp tất cả sáu phương pháp. Bộ 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) < (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last)7 đi kèm với chi phí thực hiện chậm hơn và dấu vết ngăn xếp phức tạp hơn cho các phương pháp so sánh dẫn xuất, do đó, việc xác định tất cả sáu có thể cần thiết rõ ràng trong một số trường hợp ngay cả khi hỗ trợ Python 2.6 bị giảm. Ví dụ, giả sử rằng bạn có một lớp để đại diện cho một người có 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)0 được triển khai: 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) < (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last)9, lớp sẽ trở thành: 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) < (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last) Nếu 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) < (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last)9 không thể được sử dụng hoặc nếu hiệu quả là quan trọng, tất cả các phương pháp có thể được đưa ra rõ ràng: 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 ((self.last, self.first) != (other.last, other.first)) def __lt__(self, other): return ((self.last, self.first) < (other.last, other.first)) def __le__(self, other): return ((self.last, self.first) <= (other.last, other.first)) def __gt__(self, other): return ((self.last, self.first) > (other.last, other.first)) def __ge__(self, other): return ((self.last, self.first) >= (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last) Hàm CMP
Phương pháp đặc biệt 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)0 không còn được tôn vinh trong Python 3. Trong Python 2, 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)1 đã thực hiện so sánh giữa hai đối tượng, trả về giá trị âm nếu 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)2, dương nếu 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)3 và không nếu chúng bằng nhau. def cmp(x, y): """ Replacement for built-in function cmp that was removed in Python 3 Compare the two objects x and y and return an integer according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y. """ return (x > y) - (x < y) 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ử:
Phương pháp đặc biệt 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)0 không còn được tôn vinh trong Python 3. Trong Python 2, 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)1 đã thực hiện so sánh giữa hai đối tượng, trả về giá trị âm nếu 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)2, dương nếu 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)3 và không nếu chúng bằng nhau. >>> actors = [Person('Eric', 'Idle'), ... Person('John', 'Cleese'), ... Person('Michael', 'Palin'), ... Person('Terry', 'Gilliam'), ... Person('Terry', 'Jones')] ... 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ế. >>> 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ề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 >>> 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'] Phương pháp Trong Python 3, tham số 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 ((self.last, self.first) != (other.last, other.first)) def __lt__(self, other): return ((self.last, self.first) < (other.last, other.first)) def __le__(self, other): return ((self.last, self.first) <= (other.last, other.first)) def __gt__(self, other): return ((self.last, self.first) > (other.last, other.first)) def __ge__(self, other): return ((self.last, self.first) >= (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last)4 đã được xóa và chỉ có thể sử dụng 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 ((self.last, self.first) != (other.last, other.first)) def __lt__(self, other): return ((self.last, self.first) < (other.last, other.first)) def __le__(self, other): return ((self.last, self.first) <= (other.last, other.first)) def __gt__(self, other): return ((self.last, self.first) > (other.last, other.first)) def __ge__(self, other): return ((self.last, self.first) >= (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last)6 (hoặc không có đối số nào). Không có người sửa lỗi cho sự thay đổi này.Tuy nhiên, việc phát hiện ra nó rất đơn giản: cuộc gọi 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 ((self.last, self.first) != (other.last, other.first)) def __lt__(self, other): return ((self.last, self.first) < (other.last, other.first)) def __le__(self, other): return ((self.last, self.first) <= (other.last, other.first)) def __gt__(self, other): return ((self.last, self.first) > (other.last, other.first)) def __ge__(self, other): return ((self.last, self.first) >= (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last)9 với đối số 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 ((self.last, self.first) != (other.last, other.first)) def __lt__(self, other): return ((self.last, self.first) < (other.last, other.first)) def __le__(self, other): return ((self.last, self.first) <= (other.last, other.first)) def __gt__(self, other): return ((self.last, self.first) > (other.last, other.first)) def __ge__(self, other): return ((self.last, self.first) >= (other.last, other.first)) def __repr__(self): return "%s %s" % (self.first, self.last)4 làm tăng kiểu mẫu trong Python 3. Mỗi hàm CMP phải được thay thế bằng một hàm chính.Có hai cách để làm điều này:
|