2009-06-30 40 views
24

Nhìn qua decimal.py, nó sử dụng NotImplemented trong nhiều phương pháp đặc biệt. ví dụ.Hằng số không thực hiện của Python

class A(object): 
    def __lt__(self, a): 
     return NotImplemented 

    def __add__(self, a): 
     return NotImplemented 

Các Python docs say:

NotImplemented

giá trị đặc biệt mà có thể được trả lại bởi “so sánh giàu” phương pháp đặc biệt (__eq__(), __lt__(), và bạn bè), để cho biết rằng việc so sánh không được triển khai với đối với loại khác.

Nó không nói về các phương pháp đặc biệt khác và cũng không mô tả hành vi.

Có vẻ như đó là một vật thể ma thuật nếu trả về từ các phương pháp đặc biệt khác tăng TypeError và trong các phương pháp đặc biệt "so sánh phong phú" thì không có gì.

ví dụ:

print A() < A() 

in True, nhưng

print A() + 1 

tăng TypeError, vì vậy tôi tò mò về những gì đang xảy ra và việc sử dụng/hành vi của NotImplemented là gì.

+2

Tất cả đều đúng. Bạn đã mô tả hoàn toàn NotImplemented. Câu hỏi là gì? –

+0

câu hỏi của tôi là nếu trong doc, nó đặc biệt đề cập đến phương pháp đặc biệt "so sánh giàu", phương pháp khác nên bỏ qua nó, sau khi nó chỉ là một đối tượng khác, tôi không thể tìm thấy doc giải thích hành vi chung hoặc cách xử lý NotImplemented –

Trả lời

26

NotImplemented cho phép bạn chỉ ra rằng so sánh giữa hai toán hạng đã cho chưa được triển khai (thay vì chỉ ra rằng so sánh là hợp lệ, nhưng sản lượng False, cho hai toán hạng).

Từ Python Language Reference:

Đối với đối tượng x và y, đầu tiên x.__op__(y) được xét xử. Nếu điều này không được triển khai hoặc trả về NotImplemented, y.__rop__(x) đã được thử. Nếu đây cũng là không được triển khai hoặc trả về Chưa được thực hiện, ngoại lệ TypeError được nâng lên. Nhưng thấy ngoại lệ sau đây:

ngoại lệ cho mục trước: nếu toán hạng bên trái là một thể hiện của một built-in loại hoặc một lớp kiểu mới, và các toán hạng phải là một thể hiện của một lớp con thích hợp của rằng loại hoặc lớp và ghi đè phương pháp cơ sở của __rop__(), phương pháp quyền toán hạng của __rop__() đang cố gắng trước khi phương pháp toán hạng trái của __op__() . Điều này được thực hiện sao cho lớp con hoàn toàn có thể ghi đè lên các toán tử nhị phân .Nếu không, phương pháp của toán hạng bên trái __op__() sẽ luôn luôn chấp nhận toán hạng thích hợp: khi một trường hợp của một lớp nhất định được mong đợi, một thể hiện của lớp con của lớp đó là luôn luôn chấp nhận được.

+3

ok trong hành vi chung là nếu giá trị trả về là NotImplemented, hãy thử một cái gì đó khác, nếu điều đó không thể nâng cao TypeError –

+0

Có phải là một ý tưởng tồi khi sử dụng nó trong các ngữ cảnh khác, ví dụ, một ánh xạ từ điển giữa các loại khác nhau? – endolith

4

Nó thực sự có ý nghĩa tương tự khi trở về từ __add__ kể từ __lt__, sự khác biệt là Python 2.x đang cố gắng cách khác để so sánh các đối tượng trước khi từ bỏ. Python 3.x làm tăng TypeError. Thực tế, Python cũng có thể thử những thứ khác cho __add__, xem __radd__ và (mặc dù tôi đang mờ trên đó) __coerce__.

# 2.6 
>>> class A(object): 
... def __lt__(self, other): 
...  return NotImplemented 
>>> A() < A() 
True 

# 3.1 
>>> class A(object): 
... def __lt__(self, other): 
...  return NotImplemented 
>>> A() < A() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unorderable types: A() < A() 

Xem Ordering Comparisions (3.0 docs) để biết thêm thông tin.

0

Nếu bạn trả lại từ __add__, nó sẽ hoạt động giống như đối tượng không có phương pháp __add__ và tăng TypeError.

Nếu bạn trả về NotImplemented từ một hàm so sánh phong phú, Python sẽ hoạt động như phương thức không được triển khai, tức là, nó sẽ trì hoãn việc sử dụng __cmp__.

Các vấn đề liên quan