Có thể ghi đè + = bằng Python không?Ghi đè "+ =" bằng Python? (__iadd __() method)
Trả lời
Có, ghi đè phương thức __iadd__
. Ví dụ:
def __iadd__(self, other):
self.number += other.number
return self
Bạn không nên triển khai '__iadd__' nếu lớp của bạn đại diện cho các đối tượng bất biến. Trong trường hợp đó chỉ cần thực hiện '__add__' sẽ được sử dụng để ghi đè' + = 'thay thế. Ví dụ, bạn có thể sử dụng '+ =' trên các kiểu bất biến như chuỗi và số nguyên, không thể thực hiện bằng '__iadd__'. –
@ScottGriffiths, vậy bạn có nói rằng nếu bạn đã triển khai '__add__' thì bạn không nhất thiết phải triển khai' __iadd__'? Tôi đọc câu hỏi trùng lặp mà bạn đã liên kết nhưng tôi đã nhầm lẫn vì tôi không hiểu tại sao bạn sẽ thực hiện '__add__' để nó biến đổi đối tượng –
@ScottGriffiths có nghĩa là hỏi" bạn không nhất thiết phải triển khai '__iadd__' __to sử dụng + = __? " –
http://docs.python.org/reference/datamodel.html#emulating-numeric-types
Ví dụ, để thực hiện báo cáo kết quả x + = y, trong đó x là một thể hiện của một lớp rằng có một phương pháp __iadd __(), x .__ iadd__ (y) được gọi.
Ngoài quá tải __iadd__
(nhớ tự trả lại!), Bạn cũng có thể dự phòng trên __add__
, vì x + = y sẽ hoạt động như x = x + y. (Đây là một trong những cạm bẫy của + = toán tử.)
>>> class A(object):
... def __init__(self, x):
... self.x = x
... def __add__(self, other):
... return A(self.x + other.x)
>>> a = A(42)
>>> b = A(3)
>>> print a.x, b.x
42 3
>>> old_id = id(a)
>>> a += b
>>> print a.x
45
>>> print old_id == id(a)
False
Nó thậm chí trips up experts:
class Resource(object):
class_counter = 0
def __init__(self):
self.id = self.class_counter
self.class_counter += 1
x = Resource()
y = Resource()
gì giá trị gì bạn mong đợi x.id
, y.id
, và Resource.class_counter
để có?
Ví dụ thứ hai của bạn không liên quan gì đến iadd hoặc + =. Kết quả tương tự cũng xảy ra nếu bạn sử dụng self.class_counter = self.class_counter + 1 Nó chỉ là một vấn đề phạm vi, sử dụng tự khi Tài nguyên nên được sử dụng. – FogleBird
Đây là ví dụ về cách sử dụng + = có thể dẫn đến sự cố. Nếu bạn đang quá tải __iadd__, thì bạn đang mở người dùng lớp học của bạn (bao gồm cả chính bạn) cho điều này, và, ít nhất, bạn nên biết vấn đề tồn tại trước đó. –
@FogleBird: Nó là một bản ghi nhớ bởi vì 'foo + = bar' có thể có nghĩa là" thay đổi đối tượng hiện có 'foo' đề cập đến" hoặc "gán' foo' cho đối tượng xuất phát từ biểu thức 'foo + bar'". Và điều đó xảy ra phụ thuộc vào việc 'foo' có phương thức' __iadd__' hay không. – Claudiu
Ngoài những gì được đưa ra chính xác trong câu trả lời ở trên, cần làm rõ một cách rõ ràng rằng khi __iadd__
bị ghi đè, hoạt động x += y
KHÔNG kết thúc với phương thức __iadd__
.
Thay vào đó, kết thúc bằng x = x.__iadd__(y)
. Nói cách khác, Python gán giá trị trả về của việc triển khai __iadd__
cho đối tượng bạn đang "thêm vào", SAU KHI triển khai hoàn tất.
Điều này có nghĩa là có thể biến đổi bên trái của thao tác x += y
để bước ẩn cuối cùng không thành công. Hãy xem xét những gì có thể xảy ra khi bạn đang làm tăng thêm cái gì đó là trong một danh sách:
>>> x[1] += y # x has two items
Bây giờ, nếu thực hiện __iadd__
của bạn (một phương pháp của một đối tượng ở x[1]
) sai lầm hoặc về mục đích loại bỏ các mục đầu tiên (x[0]
) từ đầu danh sách, Python sẽ chạy phương thức __iadd__
của bạn) & cố gắng gán giá trị trả về của nó cho x[1]
. Mà sẽ không còn tồn tại (nó sẽ là x[0]
), dẫn đến một ÌndexError
.
Hoặc, nếu __iadd__
chèn của bạn một cái gì đó để đầu x
của ví dụ trên, đối tượng của bạn sẽ có mặt tại x[2]
, không x[1]
, và bất cứ điều gì là trước đó tại x[0]
bây giờ sẽ có mặt tại x[1]
và được gán giá trị trả về của __iadd__
yêu cầu.
Trừ khi người ta hiểu điều gì đang xảy ra, kết quả là lỗi có thể là một cơn ác mộng cần khắc phục.
- 1. Tại sao ghi đè == phải ghi đè bằng?
- 2. Chuỗi ghi đè Python __hash__
- 3. python ghi đè dòng trước
- 4. Python: ghi đè phép nhân
- 5. Làm cách nào để ghi đè nhập bằng Python?
- 6. C++ Ghi đè ... ghi đè?
- 7. Ghi đè vùng tên trong Python
- 8. Python undo method mock
- 9. python variable method name
- 10. Ghi đè hoặc ghi đè
- 11. python: ghi đè lớp "là" hành vi
- 12. Ghi đè toán tử 'boolean' trong python?
- 13. Ghi đè phương thức ghi đè (C#)
- 14. ghi đè phương thức đệ quy trong python
- 15. ghi đè bằng phương thức() của Pair
- 16. Ghi đè bằng phương pháp trong DTO's
- 17. Ghi đè nền nội dung bằng JQuery?
- 18. Ghi đè hai SpatialPolygonsDataFrames bằng spplot
- 19. ghi đè khi chạy __setattr__
- 20. Sự khác biệt giữa ghi đè ảo, ghi đè, ghi đè mới và bị ghi
- 21. django collectstatic ghi đè
- 22. Django: ghi đè get_FOO_display()
- 23. Ghi đè phương thức ở cấp độ
- 24. Cách tạo phương thức ghi đè bằng Mono.Cecil?
- 25. ghi đè nội bộ được bảo vệ bằng bảo vệ!
- 26. Ghi đè đăng ký ghi đè Tạo Phương thức
- 27. python resizable instance method memoization decorator
- 28. Ghi đè đối tượng ghi đè với các liên kết
- 29. Ghi đè Hibernate @transient
- 30. Gọi chức năng ghi đè từ chức năng ghi đè
Bản sao chính xác của http://stackoverflow.com/questions/728361/is-there-a-way-to-overload-in-python –
có, nhưng sử dụng tìm kiếm trang web cho: + = python không có kết quả. đặt dấu ngoặc kép xung quanh "+ =" cho kết quả nhưng phần lớn không liên quan đến đánh giá bởi các tiêu đề. tìm thấy điều này thông qua một tìm kiếm của Google mặc dù. –