Python tự trang trí phương thức lớp
Chúng ta có thể dễ dàng tạo các bộ trang trí bên trong một lớp và nó có thể dễ dàng truy cập đối với các lớp con của nó. Trong quá trình tạo Trình trang trí, chúng ta phải lưu ý rằng hàm mà chúng ta đang xác định bên trong trình trang trí phải lấy tham chiếu đối tượng hiện tại (bản thân) làm tham số và trong khi chúng ta đang truy cập trình trang trí đó từ lớp con, chúng ta phải gọi trình trang trí đó bằng cách sử dụng lớp Show
ví dụ 1. Ở đây trong ví dụ này, chúng tôi đang tạo một chức năng trang trí bên trong Lớp A. Bên trong Class A “fun1” Instance Method đang gọi hàm decorator “Decorators” bên trong Class B “fun2”. Phương thức sơ thẩm đang gọi chức năng trang trí của Lớp A. Để sử dụng trình trang trí của Lớp A, chúng tôi phải yêu cầu sử dụng tên Lớp trong đó trình trang trí có mặt, đó là lý do tại sao chúng tôi sử dụng “@A. Trang trí” tại đây Giả sử chúng ta cần một decorator mà chúng ta sẽ chỉ sử dụng bên trong một lớp cụ thể. Một cái gì đó như thế này Nơi để xác định trang trí này? Chức năng bên trong lớpSự thôi thúc ngay lập tức là đưa Điều đó thực sự sẽ hiệu quả, nhưng có một lỗ hổng lớn trong cách tiếp cận này. Lưu ý rằng trong thân lớp Đây là một ví dụ nhỏ có thể giúp bạn hiểu khái niệm này Bạn thực sự có thể thấy rằng Chúng ta có thể làm gì để điều này hoạt động bình thường? Làm cho nó tĩnh (không)Điều đơn giản bạn làm mỗi khi muốn lưu trữ một hàm đơn giản trong một lớp là biến nó thành một phương thức tĩnh Bạn có thể nghĩ rằng nó giải quyết hoàn toàn mọi vấn đề, nhưng thật đáng buồn là không phải vậy. Vì vậy, khi bạn áp dụng trình trang trí này cho một phương thức nào đó, bạn sẽ nhận được Giải pháp đơn giản nhất mà bạn có thể đã nghĩ đến là khai báo hàm bên ngoài lớp Nhược điểm duy nhất là hàm không còn bị ràng buộc với lớp nữa Khai báo trong một lớp khácĐể khắc phục điều này, chúng ta có thể khai báo một lớp trợ giúp chứa tất cả các bộ trang trí cho
Bạn cũng có thể đặt Giải pháp này khá chắc chắn và được khuyên dùng, nhưng có một phương pháp hấp dẫn mà tôi biết Tạo lớp, không phải phương thứcNhờ phương thức ma thuật Sự thật thú vị. cả hai giải pháp hoạt động đều liên quan đến việc thay đổi hàm bên trong thành lớp bên trong (do hành vi cụ thể của các thuộc tính hàm, duh) Lưu ý rằng vấn đề được mô tả không có bản chất khái niệm, nó chỉ là một cách để chống lại thực tế là một hàm không thể là một thuộc tính lớp đơn giản trong Python Trình trang trí là các trình bao bọc xung quanh các hàm (hoặc lớp) Python thay đổi cách các lớp này hoạt động. Một trang trí trừu tượng hóa chức năng của chính nó càng xa càng tốt. Ký hiệu Decorator được thiết kế để ít xâm lấn nhất có thể. Nhà phát triển có thể phát triển mã của mình trong miền của mình khi anh ta đã quen và chỉ sử dụng công cụ trang trí để mở rộng chức năng. Bởi vì điều này nghe có vẻ rất trừu tượng, hãy xem xét một số ví dụ Trong Python, các bộ trang trí được sử dụng chủ yếu để trang trí các hàm (hoặc phương thức tương ứng). Có lẽ, một trong những decorator được sử dụng phổ biến nhất là 3 decoratorNhư bạn thấy ở dòng cuối cùng, bạn có thể truy cập vào 4 trong số 5 của chúng tôi giống như một thuộc tính, tôi. e. , bạn không cần phải gọi phương thức 4. Thay vào đó, khi truy cập vào 4 giống như một thuộc tính (không có 8), phương thức này được gọi hoàn toàn bởi vì trình trang trí 3Làm thế nào nó hoạt động?Viết 3 trước định nghĩa hàm tương đương với viết 1. Nói cách khác. 2 là một hàm nhận một hàm khác làm đối số và trả về một hàm thứ ba. Và đây chính xác là những gì người trang trí làmDo đó, các bộ trang trí thay đổi hành vi của chức năng được trang trí Viết trang trí tùy chỉnhThử lại Trình trang tríVới định nghĩa mơ hồ đó, hãy viết các bộ trang trí của riêng chúng ta để hiểu cách chúng hoạt động Giả sử chúng ta có một chức năng mà chúng ta muốn thử lại nếu nó không thành công. Chúng tôi cần một chức năng (trình trang trí của chúng tôi) gọi chức năng của chúng tôi một hoặc hai lần (tùy thuộc vào lần đầu tiên nó có bị lỗi hay không) Theo định nghĩa ban đầu của chúng tôi về một trình trang trí, chúng tôi có thể viết trình trang trí đơn giản này như thế này
3 là tên của trình trang trí của chúng tôi, nó chấp nhận bất kỳ chức năng nào làm đối số ( 4). Bên trong decorator, một chức năng mới (_______8_______5) được xác định và trả về. Thoạt nhìn có thể hơi lạ lẫm khi định nghĩa một hàm bên trong một hàm khác. Tuy nhiên, điều này hoàn toàn ổn về mặt cú pháp và có lợi thế là hàm 5 của chúng ta chỉ hợp lệ bên trong không gian tên của trình trang trí 3 của chúng taLưu ý rằng trong ví dụ này, chúng tôi đã trang trí chức năng của mình chỉ bằng 8. Không có dấu ngoặc đơn ( 8) sau trang trí 8. Do đó, khi gọi hàm 1 của chúng ta, trình trang trí 3 được gọi với hàm ( 3) làm đối số đầu tiênTổng cộng, chúng tôi xử lý ba chức năng ở đây Trong một số trường hợp, chúng ta cần decorator chấp nhận các đối số. Trong trường hợp của chúng tôi, chúng tôi có thể biến số lần thử lại thành tham số. Tuy nhiên, một trình trang trí phải lấy chức năng trang trí của chúng tôi làm đối số đầu tiên. Hãy nhớ rằng chúng ta không cần gọi decorator khi trang trí một chức năng với nó, tôi. e. chúng tôi vừa viết 8 thay vì 5 trước định nghĩa chức năng được trang trí của chúng tôi
Do đó, chúng ta có thể giới thiệu một hàm thứ tư chấp nhận tham số mà chúng ta muốn làm cấu hình và trả về một hàm thực sự là một hàm trang trí (chấp nhận một hàm khác làm đối số) Chúng ta hãy cố gắng này
Xé nát cái đó
Đó là định nghĩa của trang trí của chúng tôi
Đây là một ví dụ khác về một trang trí hữu ích. Hãy tạo một trình trang trí để đo thời gian chạy của các chức năng được trang trí với nó ________số 8_______ đầu ra
Như chúng ta thấy, trình trang trí 9 thực thi một số mã trước và sau chức năng được trang trí và hoạt động theo cách chính xác như trong ví dụ trước
Finished 'MyClass' in 0.0000 secs |