2010-02-15 21 views
7

Tôi mới dùng Python nên xin lỗi trước nếu đây là một câu hỏi ngu ngốc.quá tải các phép gán số học gia tăng trong python

Để được gán, tôi cần quá tải các phép gán số học tăng cường (+ =, - =,/=, * =, ** =,% =) cho một lớp myInt. Tôi đã kiểm tra tài liệu Python và đây là những gì tôi đã đưa ra:

def __iadd__(self, other): 

    if isinstance(other, myInt): 
     self.a += other.a 
    elif type(other) == int: 
     self.a += other 
    else: 
     raise Exception("invalid argument") 

self.a và other.a tham chiếu đến int được lưu trữ trong mỗi cá thể lớp. Tôi đã thử kiểm tra điều này như sau, nhưng mỗi khi tôi nhận được 'Không' thay vì giá trị kỳ vọng 5:

c = myInt(2) 
b = myInt(3) 
c += b 
print c 

Bất cứ ai có thể cho tôi biết tại sao điều này xảy ra? Cảm ơn trước.

+2

Tôi tin rằng không có câu hỏi ngu ngốc .. –

Trả lời

14

Bạn cần thêm return self vào phương pháp của mình. Giải thích:

Ngữ nghĩa của a += b, khi type(a) có một phương pháp đặc biệt __iadd__, được định nghĩa là:

a = a.__iadd__(b) 

vì vậy nếu __iadd__ lợi nhuận một cái gì đó khác với self, đó là những gì sẽ bị ràng buộc để đặt tên a sau hoạt động. Bằng cách thiếu câu lệnh return, phương thức bạn đã đăng tương đương với return None.

+1

Alex, tôi luôn yêu câu trả lời của bạn! –

+0

@Srinivas, cảm ơn! –

+0

Cảm ơn lời giải thích rõ ràng! – Mel

1

Có, bạn cần "trở lại tự", nó sẽ giống như thế này:

def __iadd__(self, other): 
    if isinstance(other, myInt): 
     self.a += other.a 
     return self 
    elif type(other) == int: 
     self.a += other 
     return self 
    else: 
     raise Exception("invalid argument") 
+2

Ngoài ra, bạn nên đặt 'Exception' thành' TypeError'. – jcdyer

7

khai thác Augmented bằng Python đã trở về giá trị cuối cùng được gán cho tên họ được kêu gọi, thông thường (và trong trường hợp của bạn) self. Giống như tất cả các phương thức Python, thiếu một câu lệnh trả về ngụ ý trả về None.

Ngoài ra,

  • Chưa bao giờ bao giờ bao giờ nâng Exception, đó là không thể để bắt sanely. Mã để làm như vậy sẽ phải nói là except Exception, mã này sẽ bắt được tất cả các trường hợp ngoại lệ. Trong trường hợp này, bạn muốn ValueError hoặc TypeError.
  • Đừng đánh máy với type(foo) == SomeType. Trong này (và hầu như tất cả) trường hợp, isinstance hoạt động tốt hơn hoặc ít nhất là như vậy.
  • Bất cứ khi nào bạn thực hiện kiểu riêng của bạn, giống như myInt, bạn nên đặt tên nó bằng chữ in hoa để mọi người có thể nhận ra đó là một tên lớp.
Các vấn đề liên quan