Tôi nhớ sử dụng kỹ thuật này từ lâu để "nâng cấp" các đối tượng hiện có sau khi nhận ra loại dữ liệu nào họ nắm giữ. Nó là một phần của ứng dụng XMPP thử nghiệm. XMPP sử dụng nhiều thông điệp XML ngắn (“stanzas”) để liên lạc.
Khi ứng dụng nhận được một đoạn văn bản, nó được phân tích thành một cây DOM. Sau đó, các ứng dụng cần thiết để nhận ra loại stanza đó là (một sự hiện diện stanza, tin nhắn, truy vấn tự động, vv). Ví dụ, nếu nó được nhận dạng như một đoạn tin nhắn, đối tượng DOM đã được “nâng cấp” lên một lớp con cung cấp các phương thức như “get_author”, “get_body”, v.v.
Tôi có thể tạo một lớp mới đại diện cho một thông điệp được phân tích cú pháp, tạo đối tượng mới của lớp đó và sao chép dữ liệu có liên quan từ đối tượng XML DOM ban đầu. Tuy nhiên, có hai lợi ích của việc thay đổi lớp của đối tượng tại chỗ. Thứ nhất, XMPP là một tiêu chuẩn rất mở rộng, và nó rất hữu ích để vẫn có thể truy cập dễ dàng vào đối tượng DOM ban đầu trong trường hợp một số phần khác của mã tìm thấy một cái gì đó hữu ích ở đó, hoặc trong khi gỡ lỗi. Thứ hai, việc viết mã cho tôi biết rằng việc tạo một đối tượng mới và sao chép dữ liệu rõ ràng chậm hơn nhiều so với việc chỉ sử dụng lại đối tượng sẽ bị phá hủy nhanh chóng — sự khác biệt là đủ để quan trọng trong XMPP, sử dụng nhiều thông điệp ngắn.
Tôi không nghĩ rằng bất kỳ lý do nào trong số này giải thích việc sử dụng kỹ thuật này trong mã sản xuất, trừ khi có thể bạn thực sự cần tốc độ (không lớn) trong CPython. Nó chỉ là một hack mà tôi thấy hữu ích để làm cho mã một chút ngắn hơn và nhanh hơn trong các ứng dụng thử nghiệm.Cũng lưu ý rằng kỹ thuật này sẽ dễ dàng phá vỡ các công cụ JIT trong việc triển khai không CPython, làm cho mã chậm hơn nhiều!
Câu trả lời này có vẻ rất kỹ lưỡng, nhưng tôi mới lập trình và do đó đấu tranh để hiểu nó. Bỏ qua khía cạnh '__new__'/constructor, tôi có thể thấy rằng nếu bạn có một lớp được định nghĩa trong thư viện ở đâu đó, và bạn đã tạo lớp của riêng bạn thừa kế nó, thì bạn có thể tạo một thể hiện của lớp sau bằng cách tạo một thể hiện của trước đây và sau đó 'chuyển đổi'. Tuy nhiên, tại sao không đơn giản là khởi tạo lớp thừa hưởng? Tôi thừa nhận tôi không hiểu các khái niệm về các hàm tạo hoặc hàm của phương thức '__new__'. – henrebotha
@henrebotha: Tôi khuyên bạn nên đọc về [mô hình dữ liệu Python] (http://docs.python.org/3/reference/datamodel.html#basic-customization). Phương thức '__new__' của lớp được gọi để xây dựng các thể hiện của nó. Gọi 'Derived()' sẽ kích hoạt một cuộc gọi đến 'Derived .__ new__' nếu nó tồn tại. Thông thường '__new__' trả về một đối tượng mới được tạo bởi' object '__ new__' (thông qua 'super' calls), nhưng nó không phải làm điều đó. Trong ví dụ trên, chúng tôi đã nhận được cá thể từ một chức năng của nhà máy, sau đó tùy chỉnh nó. Xem thêm [câu hỏi trước này] (http://stackoverflow.com/questions/15330755/construct-class-from-superclass-instance). – Blckknght