2011-08-20 30 views
19

Tôi đã viết một lớp để biểu diễn vectơ trong Python (như một bài tập) và tôi đang gặp vấn đề với việc mở rộng các toán tử dựng sẵn.Phương thức __mul__ do người dùng định nghĩa không giao hoán

Tôi đã xác định phương thức __mul__ cho lớp vectơ. Vấn đề là trong biểu thức x * y trình thông dịch gọi phương thức __mul__ của x, chứ không phải y.

Vì vậy, vector(1, 2, 3) * 2 trả về một véc tơ < 2, 4, 6> giống như nó cần; nhưng 2 * vector(1, 2, 3) tạo một TypeError vì lớp int tích hợp không hỗ trợ phép nhân bằng các vectơ do người dùng định nghĩa của tôi.

tôi có thể giải quyết vấn đề này bằng cách đơn giản viết một hàm nhân mới

def multiply(a, b): 
    try: 
     return a * b 
    except TypeError: 
     return b * a 

nhưng điều này sẽ yêu cầu xác định lại tất cả các chức năng mà tôi muốn sử dụng với lớp học của tôi dùng định nghĩa.

Có cách nào để làm cho hàm tích hợp xử lý chính xác không?

Trả lời

24

Nếu bạn muốn commutativity cho các loại khác nhau bạn cần triển khai __rmul__(). Nếu được triển khai, nó được gọi, giống như tất cả các phương thức đặc biệt __r*__(), nếu hoạt động sẽ tăng thêm TypeError. Ghi chú rằng các đối số được hoán đổi:

class Foo(object): 
    def __mul_(self, other): 
     ''' multiply self with other, e.g. Foo() * 7 ''' 
    def __rmul__(self, other): 
     ''' multiply other with self, e.g. 7 * Foo() ''' 
+0

như thế nào Python biết để gọi 'Foo .__ rmul__' và không phải là' __mul__' của đối tượng khác? –

+2

Nó cố gắng sử dụng '__mul__' ở phía bên trái, và nếu nó không thể tìm thấy, thì nó sẽ tìm kiếm' __rmul__' ở phía bên tay phải. –

+3

@pst, trước tiên Python gọi '__mul__', nhưng nếu nó không tồn tại hoặc nếu nó trả về' NotImplemented' thì Python gọi '__rmul__' của đối tượng khác. (Lưu ý rằng nếu '__mul__' tăng một phép toán,' __rmul__' được gọi là __not__. –

2

Tôi tin rằng bạn đang tìm kiếm __rmul__

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