2010-02-04 28 views
9

Làm thế nào xấu để xác định lại một phương thức lớp học từ một mô-đun bên thứ ba khác, bằng Python?Làm cách nào để ghi đè phương thức từ mô-đun của bên thứ ba?

Thực tế, người dùng có thể tạo ma trận NumPy có chứa numbers with uncertainty; lý tưởng, tôi muốn mã của họ để chạy không sửa đổi (so với khi mã thao tác ma trận nổi); đặc biệt, nó sẽ là tuyệt vời nếu nghịch đảo của ma trận m vẫn có thể thu được với m.I, mặc dù thực tế là m.I phải được tính bằng mã của riêng tôi (phương thức I ban đầu không hoạt động, nói chung).

Làm thế nào xấu để xác định lại numpy.matrix.I? Đối với một điều, nó làm giả mạo với mã của bên thứ ba, mà tôi không thích, vì nó có thể không được mạnh mẽ (nếu các module khác làm như vậy? ...). Một vấn đề khác là numpy.matrix.I mới là một trình bao bọc có liên quan đến một chi phí nhỏ khi bản gốc numpy.matrix.I thực sự có thể được áp dụng để thu được ma trận nghịch đảo.

Đang phân lớp các ma trận NumPy và chỉ thay đổi phương thức I của chúng tôi tốt hơn? điều này sẽ buộc người dùng cập nhật mã của họ và tạo ma trận các số không chắc chắn với m = matrix_with_uncert(…) (thay vì giữ sử dụng numpy.matrix(…), đối với ma trận nổi), nhưng có lẽ đây là một sự bất tiện cần được chấp nhận vì lợi ích của sự vững mạnh? Ma trận nghịch đảo vẫn có thể được thực hiện với m.I, tốt ... Mặt khác, sẽ rất tuyệt nếu người dùng có thể xây dựng tất cả ma trận của họ (nổi hoặc số không chắc chắn) với trực tiếp numpy.matrix() mà không phải bận tâm kiểm tra các kiểu dữ liệu .

Mọi nhận xét hoặc phương pháp tiếp cận bổ sung sẽ được hoan nghênh!

Trả lời

11

Phân lớp (có liên quan đến việc ghi đè, vì thuật ngữ thường được sử dụng) thường thích hợp hơn để "vá khỉ" (nhồi các phương thức đã thay đổi vào các lớp hoặc mô-đun hiện có), ngay cả khi có sẵn , có nghĩa là những cái được thực hiện trong C, có thể tự bảo vệ mình chống lại việc vá khỉ, và hầu hết chúng đều làm).Ví dụ, nếu chức năng của bạn dựa vào việc vá khỉ, nó sẽ phá vỡ và ngừng nâng cấp nếu bất cứ lúc nào lớp bạn đang vá khỉ được nâng cấp để được triển khai trong C (cho tốc độ hoặc đặc biệt để bảo vệ chống lại việc vá khỉ).). Những người bảo trì các gói của bên thứ ba ghét việc vá lỗi khỉ bởi vì nó có nghĩa là họ nhận được các báo cáo lỗi không có thật từ những người dùng không may (không biết họ) đang sử dụng một miếng vá lỗi có thể phá vỡ gói của bên thứ ba. khôn ngoan) là hoàn hảo. Bạn đã nhận xét về hiệu suất có thể đạt được.

Về mặt khái niệm, "ma trận số có độ không chắc chắn" là một khái niệm khác với "ma trận số". Subclassing thể hiện một cách sạch sẽ, khỉ-vá cố gắng che giấu nó. Đó thực sự là gốc rễ của những gì sai với khỉ vá nói chung: một kênh bí mật hoạt động thông qua các phương tiện toàn cầu, ẩn, không rõ ràng và minh bạch. Tất cả các vấn đề thực tiễn đều xuất hiện trong ý nghĩa từ vấn đề khái niệm gốc này.

I mạnh thúc giục bạn từ chối việc vá khỉ để ưu tiên các giải pháp sạch như phân lớp.

+0

Cảm ơn bạn đã mô tả rõ ràng về việc vá khỉ và các vấn đề tiềm tàng của nó! Tôi phải nói NumPy khuyến khích định nghĩa của "mảng của một cái gì đó" bằng cách hỗ trợ chúng ('numpy.array ([any_object])'). Vì vậy, tôi sẽ nói rằng "ma trận của bất kỳ loại đối tượng" là một khái niệm được hỗ trợ rất nhiều bởi bổ sung NumPy – element-wise được hỗ trợ tự động vv. Điều đó nói rằng, tôi hoàn toàn đăng ký phần còn lại của câu trả lời của bạn! – EOL

1

Nói chung, nó hoàn toàn có thể chấp nhận để ghi đè các phương pháp mà ...

  • Cố ý cho phép ghi đè
  • Trong một cách mà họ ghi lại (thỏa mãn LSP sẽ không đau)

Nếu cả hai điều kiện được đáp ứng, sau đó trọng trách nên được an toàn.

+1

Liên kết thú vị về LSP! – EOL

1

Phụ thuộc vào ý bạn với "xác định lại". Rõ ràng bạn có thể sử dụng phiên bản của riêng bạn, không có vấn đề gì cả. Ngoài ra, bạn có thể xác định lại nó bằng cách phân lớp nếu đó là một phương thức.

Bạn cũng có thể tạo một phương pháp mới và vá nó vào lớp học, một thực tế được gọi là monkey_patching. Giống như vậy:

from amodule import aclass 

def newfunction(self, param): 
    do_something() 

aclass.oldfunction = newfunction 

Điều này sẽ làm cho tất cả các trường hợp sử dụng hàm mới của bạn thay vì cũ, bao gồm cả các trường hợp trong bất kỳ mô-đun "bên thứ tư" nào. Điều này hoạt động và rất hữu ích, nhưng nó được coi là rất xấu xí và một lựa chọn cuối cùng. Điều này là do không có gì trong mã aclass để gợi ý rằng bạn đã ghi đè phương thức, do đó rất khó để gỡ lỗi. Và thậm chí tệ hơn khi hai mô-đun cũng giống nhau. Sau đó, bạn thực sự bị nhầm lẫn.

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