Python is praised for its clarity and syntactic sugariness. In this article, I will teach you to use decorators in Python to make your code readable and clean.
Python的清晰性和語法含糖度受到贊譽。 在本文中,我將教您在Python中使用裝飾器,以使您的代碼更具可讀性和簡潔性。
什么是裝飾器? (What Are Decorators?)
To understand what decorators are, you first need to be familiar with the way Python handles functions. From its point of view, functions are no different than regular objects. They have properties and can be reassigned:
要了解裝飾器是什么,首先需要熟悉Python處理函數的方式。 從它的角度來看,功能與常規對象沒有什么不同。 它們具有屬性,可以重新分配:
Moreover, you can pass them as arguments to other functions:
此外,您可以將它們作為參數傳遞給其他函數:
Now, to decorators. A decorator is used to modify the behaviour of a function or class. The way this is achieved is by defining a function (decorator) that returns another function. This sounds complicated, but you will understand everything with this example:
現在,到裝飾員。 裝飾器用于修改函數或類的行為。 實現此方法的方法是定義一個函數(裝飾器),該函數返回另一個函數。 這聽起來很復雜,但是您將通過此示例理解所有內容:
Let’s go step by step:
讓我們一步一步走:
Firstly, we define the
logging_decorator
function on line 1. It accepts a single argument, which is the function we are trying to decorate.首先,我們在第1行上定義
logging_decorator
函數。它接受一個參數,這是我們嘗試修飾的函數。Inside, we define another function: the
logging_wrapper
. Thelogging_wrapper
is then returned and used in place of the original decorated function.在內部,我們定義了另一個函數:
logging_wrapper
。 然后返回logging_wrapper
并代替原始的裝飾函數。On line 7, you can see how the decorator is applied to the
sum
function.在第7行,您可以看到裝飾器如何應用于
sum
函數。On line 11, when we call
sum
, it will not just callsum
. It will call thelogging_wrapper
, which will log before and after calling thesum
.在第11行,當我們調用
sum
,它不僅會調用sum
。 它將調用logging_wrapper
,它將在調用sum
之前和之后進行記錄。
為什么需要裝飾器? (Why Do You Need Decorators?)
It is simple: readability. Python is praised for its clear and concise syntax, and decorators are no exceptions. If there is any behaviour that is common to more than one function, you probably need to make a decorator. Here are some examples of when they might come in handy:
很簡單:可讀性。 Python因其簡潔明了的語法而廣受贊譽,裝飾器也不例外。 如果有多個功能共有的行為,則可能需要制作裝飾器。 以下是一些可能派上用場的示例:
- Checking argument type at runtime 在運行時檢查參數類型
- Benchmark function calls 基準函數調用
- Cache function results 緩存功能結果
- Count function calls 計算函數調用
- Checking metadata (permissions, roles, etc.) 檢查元數據(權限,角色等)
- Metaprogramming 元編程
- And much more… 以及更多…
Now I will list some code examples.
現在,我將列出一些代碼示例。
具有返回值的裝飾器 (Decorators With Return Values)
Suppose we want to know how long each function call takes. Also, functions return something most of the time, so the decorator must handle that as well:
假設我們想知道每個函數調用要花費多長時間。 而且,函數大多數時候會返回某些東西,因此裝飾器也必須處理該問題:
You can see we store the returned value in result
on line 5. But before returning it, we have to finish timing the function. This is an example of behaviour that would not be possible without decorators.
您可以看到我們將返回的值存儲在第5行的result
中。但是在返回它之前,我們必須完成對函數的計時。 這是沒有裝飾器就無法實現的行為示例。
帶參數的裝飾器 (Decorators With Arguments)
Sometimes, we want a decorator that accepts values (like @app.route('/login')
in Flask):
有時,我們需要一個接受值的裝飾器(例如Flask中的@app.route('/login')
):
In order to achieve that, we defined an extra function that accepts an argument and returns a decorator.
為了實現這一點,我們定義了一個額外的函數,該函數接受一個參數并返回一個裝飾器。
用課堂裝飾 (Decorating With Classes)
It is possible to decorate using classes instead of functions. The only difference is the syntax, so do what you are more comfortable with. Here is the logging decorator rewritten using classes:
可以使用類而不是函數進行裝飾。 唯一的區別是語法,所以您更喜歡它。 這是使用類重寫的日志裝飾器:
The upside is that you do not have to deal with nested functions. All you need to do is define a class and override the __call__
method.
好處是您不必處理嵌套函數。 您需要做的就是定義一個類并覆蓋__call__
方法。
裝飾類 (Decorating Classes)
There may be times when you want to decorate each and every method in a class. You could always write it like this:
有時您可能想裝飾一個類中的每個方法。 您總是可以這樣寫:
But if you have lots of methods, this can get out of hand. Thankfully, there is a way to decorate the whole class at once:
但是,如果您有很多方法,這可能會一發不可收拾。 值得慶幸的是,有一種方法可以一次裝飾整個類:
Now, do not panic. This looks complicated, but this is the same logic:
現在,不要驚慌。 這看起來很復雜,但這是相同的邏輯:
Firstly, we leave the
logging_decorator
as is. It will be applied to all methods of a class.首先,我們保持
logging_decorator
。 它將應用于類的所有方法。Then we define a new decorator:
log_all_class_methods
. It is like a regular decorator but returns a class instead.然后,我們定義一個新的裝飾器:
log_all_class_methods
。 它就像一個普通的裝飾器,但是返回一個類。The
NewCls
has a custom__getattribute__
. For all calls to the original class, it will decorate the functions with thelogging_decorator
.NewCls
有一個自定義__getattribute__
。 對于所有對原始類的調用,它將使用logging_decorator
裝飾函數。
內置裝飾器 (Built-In Decorators)
Not only can you define your own decorators, but there are some shipped in the standard library as well. I will list the three that I have worked with the most:
您不僅可以定義自己的裝飾器,而且標準庫中也有一些裝飾器。 我將列出我工作最多的三個人:
@property
— A decorator from built-ins that lets you define getters and setters for class properties.@property
property-內置的裝飾器,可讓您定義類屬性的getter和setter。@lru_cache
— A decorator from thefunctools
module. It memorizes function arguments and return values, which is handy for pure functions (like thefactorial
).@lru_cache
—functools
模塊中的裝飾器。 它存儲函數參數和返回值,這對于純函數(例如factorial
)非常方便。@abstractmethod
— A decorator from theabc
module. Indicates that the method is abstract and implementation details are missing.@abstractmethod
—來自abc
模塊的裝飾器。 表示該方法是抽象的,并且缺少實現細節。
結束語 (Closing Notes)
Thank you for reading, I hope you liked my article. Stay subscribed for more Python content!
感謝您的閱讀,希望您喜歡我的文章。 請繼續訂閱更多Python內容!
資源資源 (Resources)
PEP 318 — Decorators for Functions and Methods
PEP 318 —功能和方法的裝飾器
Higher-order functions and operations on callable objects
可調用對象的高階函數和操作
翻譯自: https://medium.com/better-programming/why-you-need-decorators-in-your-python-code-df12d43eac9c
本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。 如若轉載,請注明出處:http://www.pswp.cn/news/387998.shtml 繁體地址,請注明出處:http://hk.pswp.cn/news/387998.shtml 英文地址,請注明出處:http://en.pswp.cn/news/387998.shtml
如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!