2016-05-31 23 views
5

Tôi đang sử dụng Python 3.5.1 và bộ phân tích loại tĩnh mới MyPy v0.4.1.Tại sao xác định loại đối số cho __eq__ ném lỗi loại MyPy?

Tôi có một số mã phức tạp hơn mà tôi đã giảm xuống này lớp python có thể đơn giản nhất cần thiết để tái tạo các lỗi:

class MyObject(object): 
    def __init__(self, value: int=5) -> None: 
     self.value = value 

    def __eq__(self, other: MyObject) -> bool: 
     return self.value == other.value 

Chạy kiểm tra loại mypy test.py sản xuất các lỗi sau:

test.py: note: In class "MyObject": 
test.py:5: error: Argument 1 of "__eq__" incompatible with supertype "object" 

Lý thuyết của tôi dựa trên these docs__eq____neq__ trên đối tượng có các loại đã được xác định, đang xung đột với định nghĩa lại lớp con của tôi về các loại này. Câu hỏi của tôi là làm cách nào để xác định các loại này để đảm bảo rằng __eq__ được kiểm tra loại với loại đã chọn của tôi.

Trả lời

4

== được cho là có các đối tượng khác tùy ý, không chỉ các đối tượng thuộc loại của bạn. Nếu nó không nhận ra các đối tượng khác, nó sẽ trả về NotImplemented:

class MyObject(object): 
    def __init__(self, value: int=5) -> None: 
     self.value = value 

    def __eq__(self, other: object) -> bool: 
     if not isinstance(other, MyObject): 
      return NotImplemented 
     return self.value == other.value 

Ngoài ra, nếu bạn cần phải tham khảo MyObject cho loại gợi ý bên trong cơ thể của riêng mình, bạn cần phải sử dụng một chuỗi, 'MyObject' thay vì MyObject . MyObject chưa tồn tại.

+0

Re: đề cập đến 'MyObject' bên trong cơ thể của chính nó, tôi đã làm điều đó ở nơi khác trong mã của tôi mà không trích dẫn và tôi không nhận được lỗi nào từ MyPy: https://github.com/pirate/py-data/blob/ master/recursive_descent_parser.py # L78 –

+1

@NickSweeting: Bạn đã chạy nó chưa? [Bạn sẽ nhận được một lỗi khi bạn cố gắng để chạy nó.] (Http://ideone.com/vk5VX6) – user2357112

+0

Ah, nhờ @ user2357112, tôi chỉ cố gắng mypy-ing nó và bỏ bê để thực sự chạy nó. Thay đổi nó thành chuỗi hoạt động. –

2

Việc đọc tài liệu của bạn là đúng - bạn cần phải cung cấp phương thức (__eq__) chữ ký giống như đã có trong lớp cơ sở (object), hoặc cách khác là chữ ký dễ chấp nhận hơn.

Lý do cho điều đó là bởi vì bạn MyObject là một subtype của object, một MyObject có thể được thông qua bất cứ nơi nào mà hy vọng một object ... có nghĩa là mã mà có thể so sánh nó với bất kỳ object khác, và không có cách nào hợp pháp cho trình kiểm tra loại để khiếu nại. Vì vậy, để phản ánh điều đó, bạn cần phải viết __eq__ để mong đợi bất kỳ object nào.

Những gì bạn có thể làm là phải lên phía trước trong cơ thể của phương pháp, kiểm tra các loại và lợi nhuận (hoặc nâng một ngoại lệ):

if not isinstance(other, MyObject): 
    return False 

Rồi như those docs say, Mypy là đủ thông minh mà sau khi kiểm tra đó, nó sẽ biết rằng otherMyObject và xử lý nó tương ứng.

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