Ghi nhớ python trang trí
Trình trang trí là công cụ rất mạnh mẽ và hữu ích trong Python vì nó cho phép các lập trình viên sửa đổi hành vi của hàm hoặc lớp. Trình trang trí cho phép chúng ta nhận tham số đầu vào là một hàm khác và mở rộng tính năng cho hàm đó mà không thay đổi nội dung của nó Show
Ví dụ về hàm Decorator trong Python >>>Xem thêm. Hàm eval trong Python - Ví dụ và công dụng của hàm eval trong Python Cú pháp của hàm Decorator trong Python@gfg_decorator chắc chắn hello_decorator(). in("Gfg") '''Mã trên tương đương với - chắc chắn hello_decorator(). in("Gfg") hello_decorator = gfg_decorator(hello_decorator)''' Trong ví dụ này, gfg_decorator là một hàm có thể gọi, hàm này có thể thêm một số mã vào đầu một số hàm có thể gọi được khác như hàm hello_decorator và trả về trình bao bọc hàm >>>Tham khảo. Key learning set Python Kỹ thuật ghi nhớ (Memoization) bằng cách sử dụng Decorator trong PythonMemoration MemorationGhi nhớ là một kỹ thuật ghi lại các kết quả trung gian để chúng có thể được sử dụng nhằm tránh tính toán lặp lại và tăng tốc độ cho chương trình. Ghi nhớ có thể được sử dụng để tối ưu hóa các chương trình sử dụng đệ quy. Trong Python, ghi nhớ có thể được thực hiện với sự trợ giúp của Decorator Ví dụ về Ghi nhớVí dụ về cách tính giai cấp thừa của một số # Chương trình đệ quy đơn giản để tìm giai thừa xác thực (số) nếu số == 1 trả lại 1 khác trả về số * thực tế (num-1) in(thực tế(5)) Chương trình như trên có thể sử dụng Trình trang trí để giải quyết như sau # Chương trình giai thừa với ghi nhớ bằng cách sử dụng # trang trí. # Hàm trang trí cho hàm 'f' được thông qua # làm tham số def memoize_factorial(f). bộ nhớ = {} # Chức năng bên trong này có quyền truy cập vào bộ nhớ # và 'f' def bên trong (num). nếu num không có trong bộ nhớ. bộ nhớ [num] = f(num) trả lại bộ nhớ [num] trở lại bên trong @memoize_factorial xác thực (số). nếu số == 1. trả lại 1 khác. trả về số * thực tế (num-1) in(thực tế(5)) Giải thích về chức năng MemoizationCó thể giải thích ví dụ trên như sau
Gỡ lỗi bằng Trình trang trí trong PythonBạn có thể sử dụng Trình trang trí trong Python để loại bỏ lỗi bằng cách sử dụng funcools. wraps() in standard library of Python. Ví dụ như sau # nhập mô-đun nhập hàm # người trang trí chắc chắn make_geek_happy (func). @functools. kết thúc tốt đẹp (func) trình bao bọc def(). Neutral_message = func() happy_message = neutral_message + " Bạn đang hạnh phúc. " trả lại happy_message trả lại trình bao bọc chắc chắn nói(). """Trả về một tin nhắn trung lập""" trả lại "Xin chào. " positive_message = make_geek_happy(nói) in( positive_message()) in (nói. __Tên__) in (nói. __doc__) in (tích cực_message. __Tên__) in (tích cực_message. __doc__) Đầu ra nhận được như sau Xin chào. Bạn đang hạnh phúc nói Trả về một tin nhắn trung lập nói Trả về một tin nhắn trung lập Kết luận Có thể thấy Trình trang trí trong Python là một công cụ tuyệt vời để đóng gói các mã xung quanh hàm và lớp. Bài viết trên giới thiệu về Decorator và một số chức năng của hàm này. Hy vọng bạn có thể áp dụng các kiến thức này trong quá trình thiết lập với Python. Tìm hiểu thêm về Python và các ngôn ngữ lập trình khác thông qua các khóa học lập trình tại T3H Trong hướng dẫn về trang trí này, chúng ta sẽ xem chúng là gì, cách tạo và sử dụng chúng. Trình trang trí cung cấp một cú pháp đơn giản để gọi các hàm bậc cao hơn Theo định nghĩa, một trình trang trí là một hàm nhận một hàm khác và mở rộng hành vi của hàm sau mà không sửa đổi nó một cách rõ ràng Điều này nghe có vẻ khó hiểu, nhưng thực sự không phải vậy, đặc biệt là sau khi bạn đã xem một số ví dụ về cách thức hoạt động của các công cụ trang trí. Bạn có thể tìm thấy tất cả các ví dụ từ bài viết này tại đây Tiền thưởng miễn phí. Nhấp vào đây để truy cập vào hướng dẫn miễn phí "Sức mạnh của Trình trang trí Python" hiển thị cho bạn ba mẫu và kỹ thuật trang trí nâng cao mà bạn có thể sử dụng để viết các chương trình Pythonic rõ ràng hơn Trang trí Cheat Sheet. Nhấp vào đây để có quyền truy cập vào bảng lừa đảo trang trí Python ba trang miễn phí tóm tắt các kỹ thuật được giải thích trong hướng dẫn này Người trang trí Bảng điểm hỏi đáp. Nhấp vào đây để có quyền truy cập vào nhật ký trò chuyện dài 25 trang từ phiên Hỏi & Đáp về người trang trí Python của chúng tôi trong Slack Cộng đồng Python thực, nơi chúng tôi đã thảo luận về các câu hỏi phổ biến về người trang trí cập nhật
Chức năngTrước khi bạn có thể hiểu về decorator, trước tiên bạn phải hiểu chức năng hoạt động như thế nào. Đối với mục đích của chúng tôi, một hàm trả về một giá trị dựa trên các đối số đã cho. Đây là một ví dụ rất đơn giản >>>
Nói chung, các hàm trong Python cũng có thể có tác dụng phụ thay vì chỉ biến đầu vào thành đầu ra. Hàm 8 là một ví dụ cơ bản về điều này. nó trả về 9 trong khi có tác dụng phụ là xuất thứ gì đó ra bàn điều khiển. Tuy nhiên, để hiểu về decorator, chỉ cần nghĩ về hàm như một cái gì đó biến các đối số đã cho thành một giá trị là đủ.Ghi chú. Trong lập trình chức năng, bạn (gần như) chỉ làm việc với các chức năng thuần túy mà không có tác dụng phụ. Mặc dù không phải là ngôn ngữ chức năng thuần túy, Python hỗ trợ nhiều khái niệm lập trình chức năng, bao gồm các hàm như đối tượng hạng nhất Loại bỏ các quảng cáoĐối tượng hạng nhấtTrong Python, hàm là đối tượng hạng nhất. Điều này có nghĩa là các hàm có thể được truyền xung quanh và được sử dụng làm đối số, giống như bất kỳ đối tượng nào khác (chuỗi, int, float, danh sách, v.v.). Hãy xem xét ba chức năng sau
Ở đây, 00 và 01 là các hàm thông thường yêu cầu tên được đặt dưới dạng chuỗi. Tuy nhiên, hàm 02 mong đợi một hàm làm đối số của nó. Ví dụ, chúng ta có thể truyền cho nó hàm 00 hoặc hàm 01>>> 0Lưu ý rằng 05 đề cập đến hai chức năng, nhưng theo những cách khác nhau. 02 và 07. Hàm 07 được đặt tên không có dấu ngoặc đơn. Điều này có nghĩa là chỉ một tham chiếu đến hàm được truyền. Chức năng không được thực thi. Mặt khác, hàm 02 được viết với dấu ngoặc đơn, vì vậy nó sẽ được gọi như bình thườngchức năng bên trongCó thể định nghĩa các chức năng bên trong các chức năng khác. Các chức năng như vậy được gọi là các chức năng bên trong. Đây là một ví dụ về hàm có hai hàm bên trong 6Điều gì xảy ra khi bạn gọi hàm 10? . Đầu ra sẽ như sau>>> 8Lưu ý rằng thứ tự xác định các hàm bên trong không quan trọng. Giống như bất kỳ chức năng nào khác, quá trình in chỉ diễn ra khi các chức năng bên trong được thực thi Hơn nữa, các hàm bên trong không được xác định cho đến khi hàm cha được gọi. Chúng nằm trong phạm vi cục bộ tới 10. chúng chỉ tồn tại bên trong hàm 10 dưới dạng biến cục bộ. Hãy thử gọi 13. Bạn sẽ nhận được một lỗi 2Bất cứ khi nào bạn gọi 10, các hàm bên trong 13 và 16 cũng được gọi. Nhưng do phạm vi cục bộ của chúng, chúng không khả dụng bên ngoài chức năng 10Hàm trả về từ hàmPython cũng cho phép bạn sử dụng các hàm làm giá trị trả về. Ví dụ sau trả về một trong các hàm bên trong từ hàm 10 bên ngoài 8Lưu ý rằng bạn đang trả về 19 mà không có dấu ngoặc đơn. Nhớ lại rằng điều này có nghĩa là bạn đang trả về một tham chiếu đến hàm 19. Ngược lại 13 với dấu ngoặc đơn đề cập đến kết quả đánh giá chức năng. Điều này có thể được nhìn thấy trong ví dụ sau>>> 2Đầu ra hơi khó hiểu chỉ đơn giản có nghĩa là biến 22 đề cập đến hàm 13 cục bộ bên trong 10, trong khi 25 trỏ đến 16Giờ đây, bạn có thể sử dụng 22 và 25 như thể chúng là các hàm thông thường, mặc dù không thể truy cập trực tiếp các hàm mà chúng trỏ tới>>> 0Cuối cùng, lưu ý rằng trong ví dụ trước, bạn đã thực thi các hàm bên trong hàm cha, chẳng hạn như 13. Tuy nhiên, trong ví dụ cuối cùng này, bạn đã không thêm dấu ngoặc đơn vào các hàm bên trong— 19—khi quay lại. Bằng cách đó, bạn có một tham chiếu đến từng chức năng mà bạn có thể gọi trong tương lai. Có lý?Loại bỏ các quảng cáotrang trí đơn giảnBây giờ bạn đã thấy rằng các hàm cũng giống như bất kỳ đối tượng nào khác trong Python, bạn đã sẵn sàng để tiếp tục và xem con thú ma thuật đó là trình trang trí Python. Hãy bắt đầu với một ví dụ
Bạn có đoán được điều gì sẽ xảy ra khi bạn gọi cho 31 không? >>> 0Để hiểu điều gì đang xảy ra ở đây, hãy xem lại các ví dụ trước. Chúng tôi thực sự chỉ áp dụng mọi thứ bạn đã học được cho đến nay Cái gọi là trang trí xảy ra ở dòng sau 1Trên thực tế, tên 32 hiện trỏ đến hàm bên trong 33. Hãy nhớ rằng bạn trả về 34 như một hàm khi bạn gọi 35>>> 2Tuy nhiên, 33 có tham chiếu đến 31 ban đầu là 38 và gọi hàm đó giữa hai lệnh gọi tới 8Đơn giản thôi. decorators bọc một chức năng, sửa đổi hành vi của nó Trước khi tiếp tục, chúng ta hãy xem một ví dụ thứ hai. Vì 33 là một hàm Python thông thường nên cách trình trang trí sửa đổi một hàm có thể thay đổi linh hoạt. Để không làm phiền hàng xóm, ví dụ sau sẽ chỉ chạy mã trang trí vào ban ngày 3Nếu bạn cố gọi cho 31 sau giờ đi ngủ, sẽ không có gì xảy ra>>> 4Cú pháp đặc biệtCách bạn trang trí 31 ở trên hơi rắc rối. Trước hết, bạn phải gõ tên 32 ba lần. Ngoài ra, phần trang trí bị ẩn một chút bên dưới định nghĩa của chức năngThay vào đó, Python cho phép bạn sử dụng các bộ trang trí theo cách đơn giản hơn với ký hiệu 44, đôi khi được gọi là cú pháp “chiếc bánh”. Ví dụ sau đây thực hiện chính xác điều tương tự như ví dụ trang trí đầu tiên 5Vì vậy, 45 chỉ là một cách dễ dàng hơn để nói 46. Đó là cách bạn áp dụng một trình trang trí cho một chức năngLoại bỏ các quảng cáoTái sử dụng đồ trang tríNhớ lại rằng một trình trang trí chỉ là một hàm Python thông thường. Tất cả các công cụ thông thường để tái sử dụng dễ dàng đều có sẵn. Hãy di chuyển trình trang trí sang mô-đun riêng của nó có thể được sử dụng trong nhiều chức năng khác Tạo một tệp tên là 47 với nội dung sau 6Ghi chú. Bạn có thể đặt tên cho chức năng bên trong của mình bất cứ điều gì bạn muốn và một tên chung chung như 33 thường không sao. Bạn sẽ thấy rất nhiều người trang trí trong bài viết này. Để tách chúng ra, chúng ta sẽ đặt tên hàm bên trong cùng tên với hàm trang trí nhưng có tiền tố 49Bây giờ bạn có thể sử dụng trình trang trí mới này trong các tệp khác bằng cách nhập thông thường 7Khi bạn chạy ví dụ này, bạn sẽ thấy rằng bản gốc 31 được thực thi hai lần>>> 8Tiền thưởng miễn phí. Nhấp vào đây để truy cập vào hướng dẫn miễn phí "Sức mạnh của Trình trang trí Python" hiển thị cho bạn ba mẫu và kỹ thuật trang trí nâng cao mà bạn có thể sử dụng để viết các chương trình Pythonic rõ ràng hơn Các chức năng trang trí với các đối sốGiả sử rằng bạn có một hàm chấp nhận một số đối số. Bạn vẫn có thể trang trí nó? 9Thật không may, chạy mã này gây ra lỗi >>> 00Vấn đề là hàm bên trong 51 không nhận bất kỳ đối số nào, nhưng 52 đã được truyền cho nó. Bạn có thể khắc phục điều này bằng cách cho phép 51 chấp nhận một đối số, nhưng sau đó nó sẽ không hoạt động đối với hàm 31 mà bạn đã tạo trước đóGiải pháp là sử dụng 55 và 56 trong hàm bao bọc bên trong. Sau đó, nó sẽ chấp nhận một số đối số vị trí và từ khóa tùy ý. Viết lại 47 như sau 01Hàm bên trong 51 hiện chấp nhận bất kỳ số lượng đối số nào và chuyển chúng vào hàm mà nó trang trí. Bây giờ cả hai ví dụ về 31 và 60 của bạn đều hoạt động>>> 02Loại bỏ các quảng cáoTrả về các giá trị từ các chức năng được trang tríĐiều gì xảy ra với giá trị trả về của các chức năng được trang trí? . Giả sử bạn trang trí một chức năng đơn giản như sau 03Cố gắng sử dụng nó >>> 04Rất tiếc, trình trang trí của bạn đã ăn giá trị trả về từ hàm Bởi vì 61 không trả về giá trị một cách rõ ràng, cuộc gọi 62 đã kết thúc trả về 9Để khắc phục điều này, bạn cần đảm bảo hàm bao bọc trả về giá trị trả về của hàm trang trí. Thay đổi tệp 47 của bạn 05Giá trị trả về từ lần thực thi cuối cùng của hàm được trả về >>> 06Bạn là ai, thực sự?Một tiện lợi lớn khi làm việc với Python, đặc biệt là trong shell tương tác, là khả năng xem xét nội tâm mạnh mẽ của nó. Nội quan là khả năng của một đối tượng biết về các thuộc tính của chính nó trong thời gian chạy. Chẳng hạn, một hàm biết tên và tài liệu của chính nó >>> 07Việc xem xét nội tâm cũng hoạt động đối với các chức năng mà bạn tự xác định >>> 08Tuy nhiên, sau khi được trang trí, 31 đã rất bối rối về danh tính của mình. Bây giờ nó báo cáo là hàm bên trong 51 bên trong trình trang trí 67. Mặc dù đúng về mặt kỹ thuật, đây không phải là thông tin hữu ích lắmĐể khắc phục điều này, các nhà trang trí nên sử dụng trình trang trí 68, điều này sẽ lưu giữ thông tin về chức năng ban đầu. Cập nhật lại 47 09Bạn không cần thay đổi bất cứ điều gì về chức năng 31 được trang trí>>> 60Tốt hơn nhiều. Bây giờ 31 vẫn là chính nó sau khi trang tríChi tiết kỹ thuật. Trình trang trí 68 sử dụng hàm 73 để cập nhật các thuộc tính đặc biệt như 74 và 75 được sử dụng trong phần nội quanLoại bỏ các quảng cáoMột vài ví dụ trong thế giới thựcHãy xem xét một vài ví dụ hữu ích hơn về trang trí. Bạn sẽ nhận thấy rằng chúng sẽ chủ yếu tuân theo cùng một khuôn mẫu mà bạn đã học cho đến nay 61Công thức này là một mẫu soạn sẵn tốt để xây dựng các công cụ trang trí phức tạp hơn Ghi chú. Trong các ví dụ sau, chúng tôi sẽ giả định rằng các bộ trang trí này cũng được lưu trong tệp 47 của bạn. Nhắc lại rằng bạn có thể tải xuống tất cả các ví dụ trong hướng dẫn nàychức năng thời gianHãy bắt đầu bằng cách tạo một trình trang trí 77. Nó sẽ đo thời gian một chức năng cần để thực thi và in thời lượng ra bàn điều khiển. Đây là mã 62Trình trang trí này hoạt động bằng cách lưu trữ thời gian ngay trước khi chức năng bắt đầu chạy (tại dòng được đánh dấu 78) và ngay sau khi chức năng kết thúc (tại 79). Thời gian mà chức năng cần sau đó là sự khác biệt giữa hai (tại 80). Chúng tôi sử dụng hàm 81, hàm này thực hiện tốt công việc đo khoảng thời gian. Dưới đây là một số ví dụ về thời gian>>> 63Chạy nó cho mình. Làm việc thông qua từng dòng mã. Hãy chắc chắn rằng bạn hiểu nó hoạt động như thế nào. Tuy nhiên, đừng lo lắng nếu bạn không hiểu. Trang trí là những sinh vật tiên tiến. Cố gắng ngủ trên đó hoặc tạo một bản vẽ của chương trình Ghi chú. Trình trang trí 77 rất tuyệt nếu bạn chỉ muốn có ý tưởng về thời gian chạy các chức năng của mình. Nếu bạn muốn thực hiện các phép đo mã chính xác hơn, thay vào đó, bạn nên xem xét mô-đun 83 trong thư viện chuẩn. Nó tạm thời tắt tính năng thu gom rác và chạy nhiều thử nghiệm để loại bỏ tiếng ồn khỏi các lệnh gọi hàm nhanhMã gỡ lỗiTrình trang trí 84 sau đây sẽ in các đối số mà một hàm được gọi cùng với giá trị trả về của nó mỗi khi hàm được gọi 64Chữ ký được tạo bằng cách nối các biểu diễn chuỗi của tất cả các đối số. Các số trong danh sách sau tương ứng với các nhận xét được đánh số trong mã
Hãy xem cách trình trang trí hoạt động trong thực tế bằng cách áp dụng nó cho một hàm đơn giản với một vị trí và một đối số từ khóa 65Lưu ý cách trình trang trí 84 in chữ ký và giá trị trả về của hàm 90>>> 66Ví dụ này có vẻ không hữu ích ngay lập tức vì trình trang trí 84 chỉ lặp lại những gì bạn vừa viết. Nó mạnh hơn khi áp dụng cho các chức năng tiện lợi nhỏ mà bạn không tự gọi trực tiếpVí dụ sau đây tính toán một giá trị gần đúng với hằng số toán học e 67Ví dụ này cũng cho thấy cách bạn có thể áp dụng một trình trang trí cho một chức năng đã được xác định. Phép tính gần đúng của e dựa trên khai triển chuỗi sau Khi gọi hàm 92, bạn có thể thấy trình trang trí 84 đang hoạt động>>> 68Trong ví dụ này, bạn nhận được một giá trị gần đúng với giá trị thực e = 2. 718281828, chỉ thêm 5 số hạng Loại bỏ các quảng cáoLàm chậm mãVí dụ tiếp theo này có vẻ không hữu ích lắm. Tại sao bạn muốn làm chậm mã Python của mình? . Trình trang trí 94 sẽ ngủ một giây trước khi nó gọi chức năng trang trí 69Để xem tác dụng của trình trang trí 94, bạn thực sự cần phải tự mình chạy ví dụ>>> 80Ghi chú. Hàm 96 là một hàm đệ quy. Nói cách khác, đó là một chức năng gọi chính nó. Để tìm hiểu thêm về các hàm đệ quy trong Python, hãy xem hướng dẫn của chúng tôi về Tư duy đệ quy trong PythonTrình trang trí 94 luôn ngủ trong một giây. Sau này, bạn sẽ thấy cách kiểm soát tốc độ bằng cách chuyển đối số cho trình trang tríĐăng ký pluginNgười trang trí không cần phải bao bọc chức năng mà họ đang trang trí. Họ cũng có thể chỉ cần đăng ký rằng một chức năng tồn tại và trả lại nó khi chưa mở gói. Điều này có thể được sử dụng, ví dụ, để tạo ra một kiến trúc plug-in trọng lượng nhẹ 81Trình trang trí 98 chỉ đơn giản là lưu trữ một tham chiếu đến chức năng được trang trí trong toàn cầu 99 dict. Lưu ý rằng bạn không phải viết một hàm bên trong hoặc sử dụng 68 trong ví dụ này vì bạn đang trả về hàm ban đầu chưa sửa đổiHàm 001 chọn ngẫu nhiên một trong các hàm đã đăng ký để sử dụng. Lưu ý rằng từ điển 99 đã chứa các tham chiếu đến từng đối tượng chức năng được đăng ký làm plugin>>> 82Lợi ích chính của kiến trúc plugin đơn giản này là bạn không cần duy trì danh sách các plugin tồn tại. Danh sách đó được tạo khi các plugin tự đăng ký. Điều này làm cho việc thêm một plugin mới trở nên tầm thường. chỉ cần xác định chức năng và trang trí nó bằng 98Nếu bạn đã quen thuộc với 004 trong Python, bạn có thể thấy một số điểm tương đồng về cách thức hoạt động của kiến trúc plugin. 004 cấp quyền truy cập vào tất cả các biến toàn cục trong phạm vi hiện tại, bao gồm cả plugin của bạn>>> 83Sử dụng trình trang trí 98, bạn có thể tạo danh sách các biến thú vị được quản lý của riêng mình, chọn thủ công một số hàm từ 004 một cách hiệu quảNgười dùng đã đăng nhập chưa?Ví dụ cuối cùng trước khi chuyển sang một số trình trang trí đẹp hơn thường được sử dụng khi làm việc với khung web. Trong ví dụ này, chúng tôi đang sử dụng Flask để thiết lập trang web 008 chỉ hiển thị với người dùng đã đăng nhập hoặc được xác thực 84Mặc dù điều này đưa ra ý tưởng về cách thêm xác thực vào khung web của bạn, nhưng thông thường bạn không nên tự mình viết các loại trình trang trí này. Đối với Flask, bạn có thể sử dụng tiện ích mở rộng Flask-Login để bổ sung thêm tính năng và bảo mật Loại bỏ các quảng cáotrang trí ưa thíchCho đến giờ, bạn đã biết cách tạo các bộ trang trí đơn giản. Bạn đã hiểu khá rõ về decorator là gì và cách chúng hoạt động. Vui lòng tạm dừng bài viết này để thực hành mọi thứ bạn đã học Trong phần thứ hai của hướng dẫn này, chúng ta sẽ khám phá các tính năng nâng cao hơn, bao gồm cách sử dụng các tính năng sau
trang trí lớp họcCó hai cách khác nhau để bạn có thể sử dụng các công cụ trang trí trên các lớp. Cái đầu tiên rất gần với những gì bạn đã làm với các hàm. bạn có thể trang trí các phương thức của một lớp. Đây là một trong những động lực để giới thiệu những người trang trí trở lại trong ngày Một số trình trang trí thường được sử dụng thậm chí được tích hợp sẵn trong Python là 009, 010 và 011. Các trình trang trí 009 và 010 được sử dụng để xác định các phương thức bên trong một không gian tên lớp không được kết nối với một thể hiện cụ thể của lớp đó. Trình trang trí 011 được sử dụng để tùy chỉnh getters và setters cho các thuộc tính lớp. Mở rộng hộp bên dưới để biết ví dụ sử dụng các công cụ trang trí nàyVí dụ sử dụng trình trang trí lớp tích hợp sẵnHiển thị/Ẩn Định nghĩa sau đây của một lớp 015 sử dụng các bộ trang trí 009, 010 và 011 85Trong lớp học này
Ví dụ, lớp 015 có thể được sử dụng như sau>>> 86Hãy định nghĩa một lớp nơi chúng ta trang trí một số phương thức của nó bằng cách sử dụng các bộ trang trí 84 và 77 từ trước đó 87Sử dụng lớp này, bạn có thể thấy tác dụng của các trang trí >>> 88Một cách khác để sử dụng các công cụ trang trí trong lớp học là trang trí cho cả lớp. Ví dụ, điều này được thực hiện trong mô-đun 030 mới trong Python 3. 7 89Ý nghĩa của cú pháp tương tự như các bộ trang trí chức năng. Trong ví dụ trên, bạn có thể đã trang trí bằng cách viết 031Một cách sử dụng phổ biến của các công cụ trang trí lớp là một giải pháp thay thế đơn giản hơn cho một số trường hợp sử dụng siêu dữ liệu. Trong cả hai trường hợp, bạn đang thay đổi định nghĩa của một lớp một cách linh hoạt Viết một trình trang trí lớp rất giống với viết một trình trang trí chức năng. Sự khác biệt duy nhất là trình trang trí sẽ nhận một lớp chứ không phải một hàm làm đối số. Trên thực tế, tất cả các trình trang trí bạn thấy ở trên sẽ hoạt động như các trình trang trí lớp. Khi bạn đang sử dụng chúng trên một lớp thay vì một chức năng, tác dụng của chúng có thể không như bạn muốn. Trong ví dụ sau, trình trang trí 77 được áp dụng cho một lớp 20Trang trí một lớp học không trang trí các phương thức của nó. Nhớ lại rằng 77 chỉ là viết tắt của 034Ở đây, 77 chỉ đo thời gian cần thiết để khởi tạo lớp>>> 21Sau đó, bạn sẽ thấy một ví dụ định nghĩa một trình trang trí lớp phù hợp, cụ thể là 036, đảm bảo rằng chỉ có một thể hiện của một lớpLoại bỏ các quảng cáoĐồ trang trí làm tổBạn có thể áp dụng một số trình trang trí cho một chức năng bằng cách xếp chồng chúng lên nhau 22Hãy nghĩ về điều này khi các trình trang trí được thực hiện theo thứ tự chúng được liệt kê. Nói cách khác, 84 gọi 038, gọi 60 hoặc 040>>> 23Quan sát sự khác biệt nếu chúng ta thay đổi thứ tự của 84 và 038 24Trong trường hợp này, 038 cũng sẽ được áp dụng cho 84>>> 25Trang trí với các đối sốĐôi khi, thật hữu ích khi chuyển đối số cho người trang trí của bạn. Chẳng hạn, 038 có thể được mở rộng thành một trình trang trí 046. Số lần để thực hiện chức năng trang trí sau đó có thể được đưa ra như một đối sốĐiều này sẽ cho phép bạn làm một cái gì đó như thế này 26>>> 27Hãy suy nghĩ về cách bạn có thể đạt được điều này Cho đến nay, tên được viết sau 44 đã đề cập đến một đối tượng chức năng có thể được gọi bằng một chức năng khác. Để nhất quán, sau đó bạn cần 048 để trả về một đối tượng hàm có thể hoạt động như một công cụ trang trí. May mắn thay, bạn đã biết cách trả về hàm. Nói chung, bạn muốn một cái gì đó như sau 28Thông thường, trình trang trí tạo và trả về một hàm bao bọc bên trong, do đó, viết đầy đủ ví dụ ra sẽ cung cấp cho bạn một hàm bên trong bên trong một hàm bên trong. Mặc dù điều này nghe có vẻ giống như chương trình tương đương với bộ phim Inception, nhưng chúng tôi sẽ gỡ rối tất cả trong giây lát 29Có vẻ hơi lộn xộn, nhưng hiện tại chúng tôi chỉ đặt cùng một mẫu trang trí mà bạn đã thấy nhiều lần bên trong một 049 bổ sung xử lý các đối số cho trình trang trí. Hãy bắt đầu với chức năng trong cùng 80Hàm 050 này nhận các đối số tùy ý và trả về giá trị của hàm được trang trí, 051. Hàm bao bọc này cũng chứa vòng lặp gọi hàm được trang trí 052 lần. Điều này không khác với các chức năng bao bọc trước đó mà bạn đã thấy, ngoại trừ việc nó đang sử dụng tham số 052 phải được cung cấp từ bên ngoàiMột bước ra ngoài, bạn sẽ tìm thấy chức năng trang trí 81Một lần nữa, 054 trông giống hệt các hàm trang trí mà bạn đã viết trước đó, ngoại trừ việc nó được đặt tên khác. Đó là bởi vì chúng ta đặt tên cơ sở— 055—cho hàm ngoài cùng, là hàm mà người dùng sẽ gọiNhư bạn đã thấy, hàm ngoài cùng trả về một tham chiếu đến hàm trang trí 82Có một vài điều tế nhị xảy ra trong hàm 055
Với mọi thứ đã được thiết lập, hãy xem kết quả có như mong đợi không 26>>> 27Chỉ là kết quả mà chúng tôi đang hướng tới Loại bỏ các quảng cáoLàm ơn cho cả hai, nhưng đừng bận tâm đến bánh mìVới một chút cẩn thận, bạn cũng có thể xác định các trình trang trí có thể được sử dụng cả khi có và không có đối số. Rất có thể, bạn không cần điều này, nhưng thật tuyệt khi có sự linh hoạt Như bạn đã thấy trong phần trước, khi một trình trang trí sử dụng các đối số, bạn cần thêm một hàm bên ngoài bổ sung. Thử thách dành cho mã của bạn là tìm hiểu xem trình trang trí đã được gọi có hay không có đối số Vì hàm để trang trí chỉ được truyền trực tiếp nếu trình trang trí được gọi mà không có đối số, nên hàm phải là một đối số tùy chọn. Điều này có nghĩa là tất cả các đối số trang trí phải được chỉ định bởi từ khóa. Bạn có thể thực thi điều này bằng cú pháp 066 đặc biệt, có nghĩa là tất cả các tham số sau đây chỉ dành cho từ khóa 85Ở đây, đối số 067 đóng vai trò là điểm đánh dấu, lưu ý liệu trình trang trí có được gọi với đối số hay không
Sử dụng bản tóm tắt này trên trình trang trí 073 trong phần trước, bạn có thể viết như sau 86So sánh điều này với bản gốc 073. Những thay đổi duy nhất là tham số 067 được thêm vào và 076- 077 ở cuốiCông thức 9. 6 của Sách dạy nấu ăn Python xuất sắc cho thấy một giải pháp thay thế bằng cách sử dụng 078Những ví dụ này cho thấy rằng 073 hiện có thể được sử dụng có hoặc không có đối số 87Nhớ lại rằng giá trị mặc định của 052 là 2>>> 88trang trí nhà nướcĐôi khi, thật hữu ích khi có một trình trang trí có thể theo dõi trạng thái. Ví dụ đơn giản, chúng ta sẽ tạo một decorator đếm số lần một hàm được gọi Ghi chú. Ở phần đầu của hướng dẫn này, chúng ta đã nói về các hàm thuần túy trả về một giá trị dựa trên các đối số đã cho. Trình trang trí trạng thái hoàn toàn ngược lại, trong đó giá trị trả về sẽ phụ thuộc vào trạng thái hiện tại, cũng như các đối số đã cho Trong phần tiếp theo, bạn sẽ thấy cách sử dụng các lớp để giữ trạng thái. Nhưng trong những trường hợp đơn giản, bạn cũng có thể sử dụng thuộc tính hàm 89Trạng thái—số lần gọi hàm—được lưu trữ trong thuộc tính hàm 081 trên hàm bao bọc. Đây là tác dụng của việc sử dụng nó>>> 20Loại bỏ các quảng cáoCác lớp học với tư cách là người trang tríCách điển hình để duy trì trạng thái là sử dụng các lớp. Trong phần này, bạn sẽ thấy cách viết lại ví dụ 082 từ phần trước bằng cách sử dụng một lớp làm công cụ trang tríNhớ lại rằng cú pháp trang trí 45 chỉ là một cách dễ dàng hơn để nói 084. Do đó, nếu 085 là một lớp, thì nó cần lấy 38 làm đối số trong phương thức 087 của nó. Hơn nữa, thể hiện của lớp cần phải có thể gọi được để nó có thể thay thế cho chức năng được trang tríĐể một thể hiện của lớp có thể gọi được, bạn triển khai phương thức đặc biệt 088 21Phương thức 088 được thực thi mỗi khi bạn cố gắng gọi một thể hiện của lớp>>> 22Do đó, việc triển khai điển hình của lớp trang trí cần triển khai 087 và 088 23Phương thức 087 phải lưu trữ tham chiếu đến hàm và có thể thực hiện bất kỳ khởi tạo cần thiết nào khác. Phương thức 088 sẽ được gọi thay vì chức năng được trang trí. Về cơ bản, nó thực hiện giống như hàm 33 trong các ví dụ trước đây của chúng tôi. Lưu ý rằng bạn cần sử dụng hàm 73 thay vì 68Công cụ trang trí 097 này hoạt động giống như công cụ trang trí trong phần trước>>> 20Nhiều ví dụ trong thế giới thực hơnBây giờ chúng tôi đã đi một chặng đường dài, đã tìm ra cách tạo ra tất cả các loại trang trí. Hãy kết thúc nó, đưa kiến thức mới tìm được của chúng ta vào việc tạo thêm một vài ví dụ có thể thực sự hữu ích trong thế giới thực Làm chậm mã, xem lạiNhư đã lưu ý trước đó, triển khai trước đây của chúng tôi về 94 luôn ngủ trong một giây. Bây giờ bạn đã biết cách thêm tham số vào trình trang trí, vì vậy, hãy viết lại 94 bằng cách sử dụng đối số 600 tùy chọn để kiểm soát thời gian ngủ của nó 25Chúng tôi đang sử dụng bản soạn sẵn được giới thiệu trong phần Làm ơn cả hai, nhưng đừng bận tâm đến bánh mì để làm cho 94 có thể gọi được cả khi có và không có đối số. Chức năng đệ quy 96 tương tự như trước đó giờ ngủ hai giây giữa mỗi lần đếm 26Như trước đây, bạn phải tự chạy ví dụ để xem tác dụng của trình trang trí >>> 80Tạo SingletonMột singleton là một lớp chỉ có một thể hiện. Có một số singletons trong Python mà bạn sử dụng thường xuyên, bao gồm 9, 604 và 605. Thực tế là 9 là một đơn vị cho phép bạn so sánh với 9 bằng cách sử dụng từ khóa 608, như bạn đã thấy trong phần Làm ơn cả hai 28Sử dụng 608 chỉ trả về 604 cho các đối tượng giống hệt nhau. Trình trang trí 036 sau đây biến một lớp thành một singleton bằng cách lưu trữ phiên bản đầu tiên của lớp dưới dạng một thuộc tính. Những lần thử tạo phiên bản sau này chỉ cần trả lại phiên bản đã lưu trữ 29Như bạn thấy, trình trang trí lớp này theo cùng một khuôn mẫu như trình trang trí chức năng của chúng tôi. Sự khác biệt duy nhất là chúng tôi đang sử dụng 612 thay vì 38 làm tên tham số để chỉ ra rằng nó có nghĩa là trang trí lớpHãy xem nếu nó hoạt động >>> 00Có vẻ như rõ ràng rằng 614 thực sự là cùng một ví dụ với 615Ghi chú. Các lớp Singleton không thực sự được sử dụng thường xuyên trong Python như trong các ngôn ngữ khác. Hiệu ứng của một singleton thường được triển khai tốt hơn dưới dạng một biến toàn cục trong một mô-đun Giá trị trả về bộ đệmTrình trang trí có thể cung cấp một cơ chế tốt để lưu vào bộ nhớ đệm và ghi nhớ. Ví dụ, hãy xem định nghĩa đệ quy của dãy Fibonacci 01Mặc dù việc triển khai đơn giản nhưng hiệu suất thời gian chạy của nó rất tệ >>> 02Để tính số Fibonacci thứ mười, bạn thực sự chỉ cần tính các số Fibonacci trước đó, nhưng việc triển khai này bằng cách nào đó cần đến 177 phép tính. Nó trở nên tồi tệ hơn một cách nhanh chóng. 21891 tính toán là cần thiết cho 616 và gần 2. 7 triệu phép tính cho số thứ 30. Điều này là do mã tiếp tục tính toán lại các số Fibonacci đã biếtGiải pháp thông thường là triển khai các số Fibonacci bằng vòng lặp 617 và bảng tra cứu. Tuy nhiên, bộ nhớ đệm đơn giản của các tính toán cũng sẽ thực hiện thủ thuật 03Bộ đệm hoạt động như một bảng tra cứu, do đó, bây giờ 618 chỉ thực hiện các phép tính cần thiết một lần>>> 04Lưu ý rằng trong cuộc gọi cuối cùng tới 619, không cần tính toán mới, vì số Fibonacci thứ tám đã được tính toán cho 620Trong thư viện tiêu chuẩn, bộ đệm Ít được sử dụng gần đây nhất (LRU) có sẵn dưới dạng 621Trình trang trí này có nhiều tính năng hơn tính năng bạn đã thấy ở trên. Bạn nên sử dụng 621 thay vì viết trình trang trí bộ đệm của riêng bạn 05Tham số 623 chỉ định số lượng cuộc gọi gần đây được lưu vào bộ đệm. Giá trị mặc định là 128, nhưng bạn có thể chỉ định 624 để lưu trữ tất cả các lệnh gọi hàm. Tuy nhiên, hãy lưu ý rằng điều này có thể gây ra các vấn đề về bộ nhớ nếu bạn đang lưu vào bộ nhớ đệm nhiều đối tượng lớnBạn có thể sử dụng phương pháp 625 để xem bộ đệm hoạt động như thế nào và bạn có thể điều chỉnh nó nếu cần. Trong ví dụ của chúng tôi, chúng tôi đã sử dụng một 623 nhỏ giả tạo để xem ảnh hưởng của việc xóa các phần tử khỏi bộ đệm>>> 06Thêm thông tin về đơn vịVí dụ sau đây hơi giống với ví dụ Đăng ký plugin trước đó, ở chỗ nó không thực sự thay đổi hành vi của chức năng được trang trí. Thay vào đó, nó chỉ cần thêm 627 làm thuộc tính chức năng 07Ví dụ sau tính toán thể tích của một hình trụ dựa trên bán kính và chiều cao của nó tính bằng centimet 08Thuộc tính chức năng 628 này sau này có thể được truy cập khi cần>>> 09Lưu ý rằng bạn có thể đã đạt được điều gì đó tương tự bằng cách sử dụng chú thích chức năng 0Tuy nhiên, vì các chú thích được sử dụng cho các gợi ý kiểu nên sẽ khó kết hợp các đơn vị như chú thích với kiểm tra kiểu tĩnh Các đơn vị thậm chí còn trở nên mạnh mẽ và thú vị hơn khi được kết nối với thư viện có thể chuyển đổi giữa các đơn vị. Một thư viện như vậy là 629. Với 629 được cài đặt ( 631), chẳng hạn, bạn có thể chuyển đổi âm lượng thành inch khối hoặc gallon>>> 1Bạn cũng có thể sửa đổi trình trang trí để trả về trực tiếp một 629 633. Một 633 như vậy được tạo bằng cách nhân một giá trị với đơn vị. Trong 629, các đơn vị phải được tra cứu trong một 636. Sổ đăng ký được lưu trữ dưới dạng thuộc tính chức năng để tránh làm lộn xộn không gian tên 2Với trình trang trí 637, việc chuyển đổi các đơn vị thực tế rất dễ dàng>>> 3Xác thực JSONHãy xem xét một trường hợp sử dụng cuối cùng. Hãy xem nhanh trình xử lý tuyến đường Flask sau đây 4Ở đây chúng tôi đảm bảo rằng khóa 638 là một phần của yêu cầu. Mặc dù xác thực này hoạt động, nhưng nó thực sự không thuộc về chức năng đó. Ngoài ra, có lẽ có những tuyến đường khác sử dụng xác thực chính xác như vậy. Vì vậy, hãy để nó KHÔ và trừu tượng hóa mọi logic không cần thiết bằng một trình trang trí. Người trang trí 639 sau đây sẽ thực hiện công việc 5Trong đoạn mã trên, trình trang trí lấy một danh sách có độ dài thay đổi làm đối số để chúng ta có thể chuyển bao nhiêu đối số chuỗi nếu cần, mỗi đối số đại diện cho một khóa được sử dụng để xác thực dữ liệu JSON
Sau đó, trình xử lý định tuyến có thể tập trung vào công việc thực sự của nó—cập nhật điểm—vì nó có thể cho rằng dữ liệu JSON là hợp lệ một cách an toàn 6Phần kết luậnĐây là một hành trình khá. Bạn đã bắt đầu hướng dẫn này bằng cách tìm hiểu kỹ hơn một chút về các hàm, đặc biệt là cách chúng có thể được định nghĩa bên trong các hàm khác và được truyền xung quanh giống như bất kỳ đối tượng Python nào khác. Sau đó, bạn đã học về các bộ trang trí và cách viết chúng sao cho
Trong phần thứ hai của hướng dẫn, bạn đã thấy các trình trang trí nâng cao hơn và học cách
Bạn đã thấy rằng, để xác định một trình trang trí, bạn thường xác định một hàm trả về một hàm bao bọc. Hàm bao bọc sử dụng 55 và 56 để truyền đối số cho hàm được trang trí. Nếu bạn muốn trình trang trí của mình cũng nhận các đối số, bạn cần lồng hàm bao bọc bên trong một hàm khác. Trong trường hợp này, bạn thường kết thúc với ba câu lệnh 643Bạn có thể tìm mã từ hướng dẫn này trực tuyến Đọc thêmNếu bạn vẫn đang tìm kiếm thêm, cuốn sách Thủ thuật Python của chúng tôi có một phần về trang trí, cũng như Sách dạy nấu ăn Python của David Beazley và Brian K. Jones Để tìm hiểu sâu về cuộc thảo luận lịch sử về cách triển khai trình trang trí trong Python, hãy xem PEP 318 cũng như Wiki trang trí Python. Có thể tìm thấy nhiều ví dụ hơn về trình trang trí trong Thư viện trình trang trí Python. Mô-đun 644 có thể đơn giản hóa việc tạo trình trang trí của riêng bạn và tài liệu của nó chứa các ví dụ về trình trang trí khácNgoài ra, chúng tôi đã tập hợp một bảng lừa đảo trang trí Python ngắn và hấp dẫn dành cho bạn Trang trí Cheat Sheet. Nhấp vào đây để có quyền truy cập vào bảng lừa đảo trang trí Python ba trang miễn phí tóm tắt các kỹ thuật được giải thích trong hướng dẫn này Đánh dấu là đã hoàn thành Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. Trang trí Python 101 🐍 Thủ thuật Python 💌 Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python Gửi cho tôi thủ thuật Python » Giới thiệu về Geir Arne Hjelle Geir Arne là một Pythonista cuồng nhiệt và là thành viên của nhóm hướng dẫn Real Python » Thông tin thêm về Geir ArneMỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là Aldren Brad Đan Joanna Michael Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia Nâng cao kỹ năng Python của bạn » Bậc thầy Kỹ năng Python trong thế giới thực Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia Nâng cao kỹ năng Python của bạn » Bạn nghĩ sao? Đánh giá bài viết này Tweet Chia sẻ Chia sẻ EmailBài học số 1 hoặc điều yêu thích mà bạn đã học được là gì? Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. Nhận các mẹo để đặt câu hỏi hay và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi |