2011-11-26 46 views
22

Khi tôi sử dụng mã trong Python 2 nó hoạt động tốt trong khi Python 3 nó mang lại cho tôi những lỗipython 2 và python 3 __cmp__

class point: 

     def __init__(self,x,y): 
      self.x=x 
      self.y=y 

     def dispc(self): 
      return ('(' +str(self.x)+','+str(self.y)+')') 

     def __cmp__(self,other): 
      return ((self.x > other.x) and (self.y > other.y)) 

............... .................................................. ...

[email protected]:~/Documents/Programs$ python3 -i classes.py 
>>> p=point(2,3) 
>>> q=point(3,4) 
>>> p>q 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unorderable types: point() > point() 
>>> 
[email protected]:~/Documents/Programs$ python -i classes.py 
>>> p=point(2,3) 
>>> q=point(3,4) 
>>> p>q 
False 
>>> 

........................................ ...........................

Trong python 3, lỗi này xuất hiện trên and khi chỉ hoạt động với ==!=.

Vui lòng đề xuất giải pháp.

Trả lời

29

Bạn cần cung cấp phương thức __lt____eq__ để đặt hàng bằng Python 3. __cmp__ không còn được sử dụng.

cập nhật để đáp ứng với những câu hỏi/ý kiến ​​dưới đây

__lt__ mất selfother như các đối số, và cần phải quay trở lại dù self là ít hơn other. Ví dụ:

class Point(object): 
    ... 
    def __lt__(self, other): 
     return ((self.x < other.x) and (self.y < other.y)) 

Vì vậy, nếu bạn có tình huống sau đây:

p1 = Point(1, 2) 
p2 = Point(3, 4) 

p1 < p2 

này sẽ tương đương với:

p1.__lt__(p2) 

nào sẽ trở lại True. __eq__ sẽ trả về True nếu các điểm bằng nhau và False nếu không. Nếu bạn sử dụng functools.total_ordering trang trí theo khuyến cáo dưới đây, bạn chỉ cần cung cấp __lt____eq__:

from functools import total_ordering 

@total_ordering 
class Point(object): 
    def __lt__(self, other): 
     ... 

    def __eq__(self, other): 
     ... 
+4

Các PEP 8 khuyến cáo là cung cấp tất cả sáu so sánh phong phú. Để dễ dàng hơn, hãy sử dụng * functools.total_ordering *. –

+1

làm cách nào để sử dụng __lt và__eq__ thay cho __cmp__? –

+0

Vâng, 'lt' là viết tắt của Less Than. Nó trả về một giá trị boolean cho biết liệu 'self' có nhỏ hơn tham số khác không. Những người khác làm việc tương tự. Tôi chắc rằng bạn có thể tìm ra các chi tiết. –

8

Đây là một thay đổi lớn và có chủ ý trong Python 3. Xem here để biết thêm chi tiết.

2

Trong Python3 sáu nhà khai thác so sánh giàu

__lt__(self, other) 
__le__(self, other) 
__eq__(self, other) 
__ne__(self, other) 
__gt__(self, other) 
__ge__(self, other) 

phải được cung cấp riêng rẽ. Điều này có thể được viết tắt bằng cách sử dụng functools.total_ordering.

Tuy nhiên, điều này hầu như không đọc được và hầu như không thực tế. Tuy nhiên, bạn phải đặt các đoạn mã tương tự trong 2 funcs - hoặc sử dụng một func helper khác.

Vì vậy, hầu hết tôi thích sử dụng lớp mixin PY3__cmp__ được hiển thị bên dưới. Điều này tái thiết lập khung phương pháp __cmp__ đơn lẻ, được thực hiện và khá rõ ràng và thiết thực trong hầu hết các trường hợp. Người ta vẫn có thể ghi đè các so sánh được chọn.

dụ của bạn sẽ chỉ trở thành:

class point(PY3__cmp__): 
     ... 
     # unchanged code 

Các PY3__cmp__ mixin lớp:

PY3 = sys.version_info[0] >= 3 
if PY3: 
    def cmp(a, b): 
     return (a > b) - (a < b) 
    # mixin class for Python3 supporting __cmp__ 
    class PY3__cmp__: 
     def __eq__(self, other): 
      return self.__cmp__(other) == 0 
     def __ne__(self, other): 
      return self.__cmp__(other) != 0 
     def __gt__(self, other): 
      return self.__cmp__(other) > 0 
     def __lt__(self, other): 
      return self.__cmp__(other) < 0 
     def __ge__(self, other): 
      return self.__cmp__(other) >= 0 
     def __le__(self, other): 
      return self.__cmp__(other) <= 0 
else: 
    class PY3__cmp__: 
     pass 
+0

Tôi thích cách bạn viết các toán tử. Tuy nhiên, vui lòng giải thích tuyên bố này (a> b) - (a theBuzzyCoder

+1

@theBuzzyCoder 'bool' chỉ là một phân lớp của' int', vì vậy 'True' và' False' về cơ bản là 1 và 0, tương ứng. Vì 'cmp' trả về giá trị âm nếu đối số đầu tiên của nó nhỏ hơn đối số thứ hai, bằng không nếu đối số bằng hoặc giá trị dương, bạn có thể thấy' False - False == 0', 'True - False = = 1' và 'False - True == -1' cung cấp các giá trị trả về đúng cho' cmp'. – chepner

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