Hướng dẫn how do you compare functions in python? - làm thế nào để bạn so sánh các chức năng trong python?

Tại sao điều này không tăng lỗi thuộc tính? Đối tượng chức năng không có bất kỳ phương pháp so sánh nào. Nó sử dụng id [] bằng cách nào đó?

fun1 = lambda:x
fun2 = lambda:x
print fun1 == fun1 # True
print fun1 == fun2 # False
print fun1 > fun2 # True
print fun1 < fun2 # False
print fun1 > 1 # True

Tôi hiểu rằng nó so sánh địa chỉ, nhưng làm thế nào? Có phải một số hack cấp thấp vào để chặn __lt__, __eq__, v.v.?

Charles

50,5K13 Huy hiệu vàng103 Huy hiệu bạc141 Huy hiệu đồng13 gold badges103 silver badges141 bronze badges

hỏi ngày 29 tháng 10 năm 2011 lúc 23:30Oct 29, 2011 at 23:30

__eq__,

>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
0 et al. Đừng thực hiện các so sánh trong Python, họ chỉ cho phép bạn ghi đè lên nó.

Các tài liệu tham khảo ngôn ngữ Python trạng thái:

Hầu hết các đối tượng khác của các loại tích hợp so sánh không đồng đều trừ khi chúng là cùng một đối tượng; Sự lựa chọn cho dù một đối tượng được coi là nhỏ hơn hay lớn hơn một đối tượng khác được thực hiện tùy ý nhưng nhất quán trong một lần thực hiện chương trình.

Có thể điều này được thực hiện bằng cách so sánh ID đối tượng nhưng điều này không được chỉ định bởi ngôn ngữ.

Tôi không chắc lý do là gì đằng sau việc tạo ra bất kỳ đối tượng nào có thể so sánh với bất kỳ đối tượng nào khác, nhưng đó là một tính năng tích hợp của ngôn ngữ-tham chiếu không đề cập đến nó làm cho bất kỳ danh sách nào có thể sắp xếp, giúp định nghĩa so sánh hai từ điển dễ dàng hơn.

Đã trả lời ngày 29 tháng 10 năm 2011 lúc 23:41Oct 29, 2011 at 23:41

milimoosemillimoosemillimoose

38.4K9 Huy hiệu vàng78 Huy hiệu bạc134 Huy hiệu đồng9 gold badges78 silver badges134 bronze badges

1

Hướng dẫn chuyển Python 3 bảo thủ

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.

Ví dụ, trong Python 2, so sánh các hoạt động của

>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
1 và
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
2 [với kết quả không thể đoán trước được trong các 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:

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

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ú

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

Phương pháp đặc biệt

>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
3 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[]
4 đã 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[]
5, dương nếu
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
6 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ànhPhương pháp
==
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
7
! =
>>> 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
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
> =
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

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ề

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 để 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 đã 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]
4 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

>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
7,
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
8 và chỉ một trong các nhà khai thác đặt hàng và sử dụng trình trang trí
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]
9 để đ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] >> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
3 đượ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] >> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
3 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[]
4 đã 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[]
5, dương nếu
>>> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
6 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 >> 2 < '2'
Traceback [most recent call last]:
File "", line 1, in 
TypeError: unorderable types: int[] < str[]
3 không còn được tôn vinh trong Python 3.

Ví dụ: đưa ra một danh sách các phiên bản của một lớp một người [được xác định ở trên]:

>>> actors = [Person['Eric', 'Idle'],
...           Person['John', 'Cleese'],
...           Person['Michael', 'Palin'],
...           Person['Terry', 'Gilliam'],
...           Person['Terry', 'Jones']]
...

Một cách để sắp xếp nó theo họ trong Python 2 sẽ là:

>>> 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']

Hàm này được gọi là nhiều lần - O [n log n] - trong quá trình so sánh.

Thay thế cho CMP, việc sắp xếp các chức năng có thể lấy 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 __repr__[self]:
        return "%s %s" % [self.first, self.last]
1 chỉ có từ khóa, một hàm trả về khóa theo đó để sắp xếp:

>>> 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']

Ưu điểm của phương pháp này là chức năng này chỉ được gọi một lần cho mỗi mục. Khi các loại đơn giản như bộ dữ liệu, chuỗi và số được sử dụng cho các khóa, nhiều so sánh sau đó được xử lý bằng mã C được tối ưu hóa. Ngoài ra, trong hầu hết các trường hợp, các chức năng chính dễ đọc hơn CMP: Thông thường, mọi người nghĩ đến việc sắp xếp theo một số khía cạnh của một đối tượng [chẳng hạn như tên cuối cùng], thay vì so sánh các đối tượng riêng lẻ. Nhược điểm chính là kiểu CMP cũ thường được sử dụng trong các API ngôn ngữ C, do đó các thư viện bên ngoài có khả năng cung cấp các chức năng tương tự.

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] 

Bài Viết Liên Quan

Chủ Đề