Như đã giải thích trong Special Method Lookup:
Đối với các lớp học tùy chỉnh, lời gọi ngầm của phương pháp đặc biệt chỉ được bảo đảm để làm việc một cách chính xác nếu định nghĩa vào loại của một đối tượng, không có trong từ điển thể hiện của đối tượng… Ngoài việc bỏ qua bất kỳ thuộc tính thể hiện nào theo sở thích của tính chính xác, tìm kiếm phương pháp đặc biệt ngầm cũng thường bỏ qua phương thức __getattribute__()
ngay cả trong metaclass của đối tượng
(Phần tôi đã giải thích lý do đằng sau điều này, nếu bạn quan tâm đến điều đó.)
Python không ghi lại chính xác khi triển khai nên hoặc không nên tra cứu phương pháp trên loại; tất cả các tài liệu đó là, có hiệu lực, việc triển khai đó có thể hoặc không thể xem xét cá thể cho các tra cứu phương pháp đặc biệt, vì vậy bạn không nên dựa vào một trong hai.
Như bạn có thể đoán từ kết quả thử nghiệm của mình, trong triển khai CPython, __repr__
là một trong các hàm được tra cứu trên loại.
Mọi thứ hơi khác biệt trong 2.x, chủ yếu là do sự hiện diện của các lớp học cổ điển, nhưng miễn là bạn chỉ tạo các lớp kiểu mới mà bạn có thể nghĩ chúng giống nhau.
Lý do phổ biến nhất mọi người muốn thực hiện điều này là để khỉ vá các trường hợp khác nhau của một đối tượng để làm những việc khác nhau. Bạn không thể làm điều đó với các phương pháp đặc biệt, vì vậy ... bạn có thể làm gì? Có một giải pháp sạch sẽ, và một giải pháp hacky.
Giải pháp sạch là triển khai phương pháp đặc biệt trên lớp chỉ cần gọi phương thức thông thường trên cá thể. Sau đó, bạn có thể khỉ vá rằng phương pháp thường xuyên trên mỗi trường hợp. Ví dụ:
class C(object):
def __repr__(self):
return getattr(self, '_repr')()
def _repr(self):
return 'Boring: {}'.format(object.__repr__(self))
c = C()
def c_repr(self):
return "It's-a me, c_repr: {}".format(object.__repr__(self))
c._repr = c_repr.__get__(c)
Giải pháp hack là xây dựng một phân lớp mới khi đang bay và sắp xếp lại đối tượng. Tôi nghi ngờ bất cứ ai thực sự có một tình huống mà đây là một ý tưởng tốt sẽ biết làm thế nào để thực hiện nó từ câu đó, và bất cứ ai không biết làm thế nào để làm như vậy không nên cố gắng, vì vậy tôi sẽ để nó ở đó.
Có thể bạn sẽ nhận được phản hồi sáng suốt hơn nhiều nếu bạn nói những gì bạn đang cố gắng đạt được. – mattmanser
Đối với các lớp kiểu mới, các phương thức đặc biệt được tra cứu trên lớp chứ không phải là cá thể. Xem câu trả lời của tôi dưới đây để biết thêm chi tiết và để giải quyết một số vấn đề. –
Tôi không thể mô tả những gì tôi muốn làm một cách chi tiết. Lấy làm tiếc. Nhưng trong ngắn hạn, tôi đang cố gắng để mô hình hóa một mô hình OO nguyên mẫu nơi tôi có thể làm các toán tử như: World = Object(). Clone(). Mixin (World); Trường hợp World là một lớp với một tập hợp các phương thức ghi đè/thay thế một phương thức trong cá thể Object.clone(). –