Trình trang trí python với các đối số tự
Làm cách nào để chuyển trường lớp tới trình trang trí trên phương thức lớp làm đối số? Show
Nó phàn nàn rằng self không tồn tại khi chuyển 46 cho người trang trí. Có cách nào để giái quyết vấn đề này không?Giải pháp tốt nhấtĐúng. Thay vì chuyển thuộc tính thể hiện vào thời điểm định nghĩa lớp, hãy kiểm tra nó khi chạy
Trình trang trí chặn các đối số của phương thức; . Bạn có thể chuyển tên thuộc tính dưới dạng chuỗi cho trình trang trí và sử dụng 47 nếu bạn không muốn mã hóa tên thuộc tính
Giải pháp liên quanPython – Tại sao bạn cần có đối số “self” một cách rõ ràng trong phương thức PythonTôi thích trích dẫn Zen of Python của Peters. "Rõ ràng là tốt hơn ngầm. " Trong Java và C++, ' 48' có thể được suy ra, trừ khi bạn có các tên biến không thể suy ra được. Vì vậy, đôi khi bạn cần nó và đôi khi khôngPython chọn làm những thứ như thế này rõ ràng hơn là dựa trên quy tắc Ngoài ra, vì không có gì được ngụ ý hoặc giả định, nên các phần của quá trình triển khai sẽ bị lộ. 49, 0 và các cấu trúc "nội bộ" khác có sẵn một cách rõ ràngPython – Các biến lớp tĩnh có thể có trong PythonCác biến được khai báo bên trong định nghĩa lớp, nhưng không bên trong một phương thức là các biến lớp hoặc biến tĩnh
Như @ đã chỉ ra, điều này tạo ra một biến 1 cấp lớp, nhưng biến này khác với bất kỳ biến 1 cấp thể hiện nào, vì vậy bạn có thể có
Điều này khác với C++ và Java, nhưng không quá khác với C#, nơi không thể truy cập thành viên tĩnh bằng cách sử dụng tham chiếu đến một thể hiện Nhìn thấy @Steve Johnson đã trả lời về các phương pháp tĩnh, cũng được ghi lại dưới ________số 8@beidy khuyến nghị s trên staticmethod, vì phương thức này sau đó nhận loại lớp làm đối số đầu tiên, nhưng tôi vẫn hơi mờ về những ưu điểm của phương pháp này so với staticmethod. Nếu bạn cũng vậy, thì có lẽ không thành vấn đề 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 >>> 0Nó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 3Ở đây, 300 và 301 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 302 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 300 hoặc hàm 301>>> 9Lưu ý rằng 305 đề cập đến hai chức năng, nhưng theo những cách khác nhau. 302 và 307. Hàm 307 đượ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 hiện. Ngược lại, hàm 302 được viết trong dấu ngoặc đơn nê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 5Điều gì xảy ra khi bạn gọi hàm 310? . Đầu ra sẽ như sau>>> 7Lư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 310. chúng chỉ tồn tại bên trong hàm 310 dưới dạng biến cục bộ. Hãy thử gọi 313. Bạn sẽ nhận được một lỗi 1Bất cứ khi nào bạn gọi 310, các hàm bên trong 313 và 316 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 310Hà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 bên ngoài 310 7Lưu ý rằng bạn đang trả về 319 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 319. Ngược lại 313 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>>> 1Đầu ra hơi khó hiểu chỉ đơn giản có nghĩa là biến 322 đề cập đến hàm 313 cục bộ bên trong 310, trong khi 325 trỏ đến 316Giờ đây, bạn có thể sử dụng 322 và 325 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>>> 9Cuố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ư 313. 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— 319—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 331 không? >>> 30Để 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 31Trên thực tế, tên 332 hiện trỏ đến hàm bên trong 333. Hãy nhớ rằng bạn trả về 334 như một hàm khi bạn gọi 335>>> 32Tuy nhiên, 333 có tham chiếu đến 331 ban đầu là 338 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ì 333 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 33Nếu bạn cố gọi cho 331 sau giờ đi ngủ, sẽ không có chuyện gì xảy ra>>> 34Cú pháp đặc biệtCách bạn trang trí 331 ở trên hơi rườm rà. Trước hết, bạn phải gõ tên 332 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 344, đôi khi được gọi là. 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 35Vì vậy, 345 chỉ là một cách dễ dàng hơn để nói 346. Đó 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à 347 với nội dung sau 36Ghi 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ư 333 thường được chấp nhận. 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ố 349Bâ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 37Khi bạn chạy ví dụ này, bạn sẽ thấy rằng bản gốc 331 được thực thi hai lần>>> 38Tiề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ó? 39Thật không may, chạy mã này gây ra lỗi >>> 90Vấn đề là hàm bên trong 351 không nhận bất kỳ đối số nào, nhưng 352 đã được truyền cho nó. Bạn có thể khắc phục điều này bằng cách cho phép 351 chấp nhận một đối số, nhưng sau đó nó sẽ không hoạt động đối với hàm 331 mà bạn đã tạo trước đóGiải pháp là sử dụng 355 và 356 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 347 như sau 91Hàm bên trong 351 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ề 331 và 360 của bạn đều hoạt động>>> 92Loạ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 93Cố gắng sử dụng nó >>> 94Rất tiếc, trình trang trí của bạn đã ăn giá trị trả về từ hàm Bởi vì 361 không trả về giá trị một cách rõ ràng, cuộc gọi 362 đã 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 347 của bạn 95Giá trị trả về từ lần thực thi cuối cùng của hàm được trả về >>> 96Bạ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ó >>> 97Việ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 >>> 98Tuy nhiên, sau khi được trang trí, 331 đã 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 351 bên trong trình trang trí 367. 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, người trang trí nên sử dụng bộ trang trí, bộ trang trí này sẽ lưu giữ thông tin về chức năng ban đầu. Cập nhật lại 347 99Bạn không cần thay đổi bất cứ điều gì về chức năng 331 được trang trí>>> 50Tốt hơn nhiều. Bây giờ 331 vẫn là chính nó sau khi trang tríChi tiết kỹ thuật. Trình trang trí 368 hàm 373 để cập nhật các thuộc tính đặc biệt như 374 và 375 đượ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 51Cô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 347 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í 377. 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ã 52Trì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 ____1378) và ngay sau khi chức năng kết thúc (tại ____1379). Thời gian mà chức năng cần sau đó là sự khác biệt giữa hai (tại 380). Chúng tôi sử dụng chức năng 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>>> 53Chạ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í 377 rất tuyệt nếu bạn chỉ muốn biết 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 383 trong thư viện chuẩn. Nó tạm thời vô hiệu hóa và chạy nhiều thử nghiệm để loại bỏ tiếng ồn khỏi các cuộc gọi chức năng nhanhMã gỡ lỗiTrình trang trí 384 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 54Chữ 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 55Lưu ý cách trình trang trí 384 in chữ ký và giá trị trả về của hàm 390>>> 56Ví dụ này có vẻ không hữu ích ngay lập tức vì trình trang trí 384 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 57Ví 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 392, bạn có thể thấy trình trang trí 384 đang hoạt động>>> 58Trong 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í 394 sẽ ngủ một giây trước khi nó gọi chức năng trang trí 59Để xem tác dụng của trình trang trí 394, bạn thực sự cần phải tự mình chạy ví dụ>>> 70Ghi chú. Hàm 396 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í 394 luôn ngủ trong một giâ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ẹ 71Trình trang trí 398 chỉ đơn giản là lưu trữ một tham chiếu đến chức năng được trang trí trong lệnh chính tả 399 toàn cầu. Lưu ý rằng bạn không cần phải viết một hàm bên trong hoặc sử dụng 368 trong ví dụ này vì bạn đang trả về hàm ban đầu chưa sửa đổiHàm 901 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 399 đã chứa các tham chiếu đến từng đối tượng chức năng được đăng ký làm plugin>>> 72Lợ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 398Nếu bạn đã quen thuộc với 904 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. 904 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>>> 73Sử dụng trình trang trí 398, 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ừ 904 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 908 chỉ hiển thị với người dùng đã đăng nhập hoặc được xác thực 74Mặ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 thay thế, điều này bổ sung thêm tính bảo mật và chức năng 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. Điều này là để 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à 909, 910 và 911. Các trình trang trí 909 và 910 đượ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í 911 đượ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 lớp 915 sử dụng các bộ trang trí 909, 910 và 911 75Trong lớp học này
Ví dụ, lớp 915 có thể được sử dụng như sau>>> 76Hã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 và trang trí từ 77Sử dụng lớp này, bạn có thể thấy tác dụng của các trang trí >>> 78Mộ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 930 mới trong Python 3. 7 79Ý 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 931A 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ả những người trang trí sẽ hoạt động như những người 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í 377 được áp dụng cho một lớp 10Trang 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 377 chỉ là viết tắt của 934Ở đây, 377 chỉ đo thời gian cần thiết để khởi tạo lớp>>> 11, 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à 936, đả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 12Hã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, 384 gọi 938, gọi 360 hoặc 940>>> 13Quan sát sự khác biệt nếu chúng ta thay đổi thứ tự của 384 và 938 14Trong trường hợp này, 938 cũng sẽ được áp dụng cho 384>>> 15Trang 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, 938 có thể được mở rộng thành một trang trí 946. 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 16>>> 17Hã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 344 đã đề 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 948 để 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. Nói chung, bạn muốn một cái gì đó như sau 18Thô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 19Có vẻ hơi lộn xộn, nhưng chúng tôi chỉ đặt cùng một mẫu trang trí mà bạn đã thấy nhiều lần vào bên trong một 949 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 70Hàm 950 này nhận các đối số tùy ý và trả về giá trị của hàm được trang trí, 951. Hàm bao bọc này cũng chứa vòng lặp gọi hàm được trang trí 952 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ố 952 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í 71Một lần nữa, 954 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 tôi đặt tên cơ sở— 955—cho chức năng ngoài cùng, là chức năng 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í 72Có một vài điều tế nhị xảy ra trong hàm 955
Với mọi thứ đã được thiết lập, hãy xem kết quả có như mong đợi không 16>>> 17Chỉ 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 966 đặc biệt, có nghĩa là tất cả các tham số sau đây chỉ dành cho từ khóa 75Ở đây, đối số 967 đó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í 973 trong phần trước, bạn có thể viết như sau 76So sánh điều này với bản gốc 973. Những thay đổi duy nhất là tham số 967 được thêm vào và 976- 977 ở 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 Những ví dụ này cho thấy rằng 973 hiện có thể được sử dụng có hoặc không có đối số 77Nhớ lại rằng giá trị mặc định của 952 là 2>>> 78trang 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ú. Trong , 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 này, 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 79Trạng thái—số lần gọi hàm—được lưu trữ trong thuộc tính hàm 981 trên hàm bao bọc. Đây là tác dụng của việc sử dụng nó>>> 10Loạ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ụ 982 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í 345 chỉ là một cách dễ dàng hơn để nói 984. Do đó, nếu 985 là một lớp, thì nó cần lấy 338 làm đối số trong phương thức 987 của nó. Hơn nữa, thể hiện của lớp cần phải sao cho 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 988 11Phương thức 988 được thực thi mỗi khi bạn cố gắng gọi một thể hiện của lớp>>> 12Do đó, một triển khai điển hình của lớp trang trí cần triển khai 987 và 988 13Phương thức 987 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 988 sẽ được gọi thay vì hàm được trang trí. Về cơ bản, nó thực hiện giống như hàm 333 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 chức năng thay vì 368Công cụ trang trí 997 này hoạt động giống như công cụ trang trí trong phần trước>>> 10Nhiề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 đó, chúng tôi 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 394 bằng cách sử dụng đối số 500 tùy chọn để kiểm soát thời gian ngủ của nó 15Chúng tôi đang sử dụng bản soạn sẵn được giới thiệu trong phần này để làm cho 394 có thể gọi được cả khi có và không có đối số. Hàm đệ quy tương tự 396 hiện ngủ hai giây giữa mỗi lần đếm 16Như trước đây, bạn phải tự chạy ví dụ để xem tác dụng của trình trang trí >>> 70Tạ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, 504 và 505. 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 508, như bạn đã thấy trong phần 18Sử dụng 508 chỉ trả về 504 cho các đối tượng giống hệt nhau. Trình trang trí 936 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ữ 19Như 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 512 thay vì 338 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 >>> 90Có vẻ như rõ ràng rằng 514 thực sự là cùng một ví dụ với 515Ghi 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 91Mặ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ệ >>> 92Để 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. Cần tính toán 21891 cho 516 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 517 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 93Bộ đệm hoạt động như một bảng tra cứu, do đó, bây giờ 518 chỉ thực hiện các phép tính cần thiết một lần>>> 94Lưu ý rằng trong cuộc gọi cuối cùng tới 519, không cần tính toán mới, vì số Fibonacci thứ tám đã được tính toán cho 520Trong thư viện tiêu chuẩn, bộ nhớ đệm Ít được sử dụng Gần đây nhất (LRU) có sẵn dưới dạng Trì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 521 thay vì viết trình trang trí bộ đệm của riêng bạn 95Tham số 523 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 524 để 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 525 để 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 523 nhỏ giả tạo để xem tác động của việc xóa các phần tử khỏi bộ đệm>>> 96Thêm thông tin về đơn vịVí dụ sau hơi giống với ví dụ trước đó, ở chỗ nó không thực sự thay đổi hành vi của hàm được trang trí. Thay vào đó, nó chỉ cần thêm 527 làm thuộc tính chức năng 97Ví 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 98Thuộc tính hàm 528 này sau này có thể được truy cập khi cần>>> 99Lư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 ý loại, sẽ khó kết hợp các đơn vị như chú thích với 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à 529. Ví dụ, với 529 đã cài đặt ( 531), 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ả lại trực tiếp một 529 533. Một 533 như vậy được tạo bằng cách nhân một giá trị với đơn vị. Trong 529, các đơn vị phải được tra cứu trong một 536. 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í 537, 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 538 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í 539 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 xem xét 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 355 và 356 để 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 bằng ba câu lệnh 543Bạ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 544 có thể đơn giản hóa việc tạo trình trang trí của riêng bạn và mô-đun này 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. 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 Trình trang trí Python có thể lấy đối số không?Các đối số của trình trang trí có thể truy cập được đối với trình trang trí bên trong thông qua một bao đóng , chính xác như cách hàm bên trong wrap() có thể truy cập f. Và vì các bao đóng mở rộng đến tất cả các cấp độ của các hàm bên trong, nên arg cũng có thể truy cập được từ bên trong wrap() nếu cần.
Người trang trí có thể tự truy cập không?Nếu bạn muốn truy cập self (ví dụ nơi trình trang trí được gọi từ đó) bạn có thể sử dụng args[0] bên trong trình trang trí .
Trình trang trí @classmethod trong Python là gì?Trong Python, trình trang trí @classmethod được dùng để khai báo một phương thức trong lớp dưới dạng một phương thức lớp có thể được gọi bằng Tên lớp. Tên phương thức() . Phương thức lớp cũng có thể được gọi bằng cách sử dụng một đối tượng của lớp. @classmethod là một thay thế của hàm classmethod().
Công cụ trang trí Staticmethod trong Python là gì?@staticmethod là trình trang trí tích hợp xác định một phương thức tĩnh trong lớp trong Python . Một phương thức tĩnh không nhận bất kỳ đối số tham chiếu nào cho dù nó được gọi bởi một thể hiện của một lớp hay bởi chính lớp đó. |