为什么在Python代码中需要装饰器
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的清晰性和語(yǔ)法含糖度受到贊譽(yù)。 在本文中,我將教您在Python中使用裝飾器,以使您的代碼更具可讀性和簡(jiǎn)潔性。
什么是裝飾器? (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處理函數(shù)的方式。 從它的角度來(lái)看,功能與常規(guī)對(duì)象沒(méi)有什么不同。 它們具有屬性,可以重新分配:
Moreover, you can pass them as arguments to other functions:
此外,您可以將它們作為參數(shù)傳遞給其他函數(shù):
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:
現(xiàn)在,到裝飾員。 裝飾器用于修改函數(shù)或類的行為。 實(shí)現(xiàn)此方法的方法是定義一個(gè)函數(shù)(裝飾器),該函數(shù)返回另一個(gè)函數(shù)。 這聽(tīng)起來(lái)很復(fù)雜,但是您將通過(guò)此示例理解所有內(nèi)容:
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.
首先,我們?cè)诘?行上定義logging_decorator函數(shù)。它接受一個(gè)參數(shù),這是我們嘗試修飾的函數(shù)。
Inside, we define another function: the logging_wrapper. The logging_wrapper is then returned and used in place of the original decorated function.
在內(nèi)部,我們定義了另一個(gè)函數(shù): logging_wrapper 。 然后返回logging_wrapper并代替原始的裝飾函數(shù)。
On line 7, you can see how the decorator is applied to the sum function.
在第7行,您可以看到裝飾器如何應(yīng)用于sum函數(shù)。
On line 11, when we call sum, it will not just call sum. It will call the logging_wrapper, which will log before and after calling the sum.
在第11行,當(dāng)我們調(diào)用sum ,它不僅會(huì)調(diào)用sum 。 它將調(diào)用logging_wrapper ,它將在調(diào)用sum之前和之后進(jìn)行記錄。
為什么需要裝飾器? (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:
很簡(jiǎn)單:可讀性。 Python因其簡(jiǎn)潔明了的語(yǔ)法而廣受贊譽(yù),裝飾器也不例外。 如果有多個(gè)功能共有的行為,則可能需要制作裝飾器。 以下是一些可能派上用場(chǎng)的示例:
- Checking argument type at runtime 在運(yùn)行時(shí)檢查參數(shù)類型
- Benchmark function calls 基準(zhǔn)函數(shù)調(diào)用
- Cache function results 緩存功能結(jié)果
- Count function calls 計(jì)算函數(shù)調(diào)用
- Checking metadata (permissions, roles, etc.) 檢查元數(shù)據(jù)(權(quán)限,角色等)
- Metaprogramming 元編程
- And much more… 以及更多…
Now I will list some code examples.
現(xiàn)在,我將列出一些代碼示例。
具有返回值的裝飾器 (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:
假設(shè)我們想知道每個(gè)函數(shù)調(diào)用要花費(fèi)多長(zhǎng)時(shí)間。 而且,函數(shù)大多數(shù)時(shí)候會(huì)返回某些東西,因此裝飾器也必須處理該問(wèn)題:
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.
您可以看到我們將返回的值存儲(chǔ)在第5行的result中。但是在返回它之前,我們必須完成對(duì)函數(shù)的計(jì)時(shí)。 這是沒(méi)有裝飾器就無(wú)法實(shí)現(xiàn)的行為示例。
帶參數(shù)的裝飾器 (Decorators With Arguments)
Sometimes, we want a decorator that accepts values (like @app.route('/login') in Flask):
有時(shí),我們需要一個(gè)接受值的裝飾器(例如Flask中的@app.route('/login') ):
In order to achieve that, we defined an extra function that accepts an argument and returns a decorator.
為了實(shí)現(xiàn)這一點(diǎn),我們定義了一個(gè)額外的函數(shù),該函數(shù)接受一個(gè)參數(shù)并返回一個(gè)裝飾器。
用課堂裝飾 (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:
可以使用類而不是函數(shù)進(jìn)行裝飾。 唯一的區(qū)別是語(yǔ)法,所以您更喜歡它。 這是使用類重寫(xiě)的日志裝飾器:
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.
好處是您不必處理嵌套函數(shù)。 您需要做的就是定義一個(gè)類并覆蓋__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:
有時(shí)您可能想裝飾一個(gè)類中的每個(gè)方法。 您總是可以這樣寫(xiě):
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:
但是,如果您有很多方法,這可能會(huì)一發(fā)不可收拾。 值得慶幸的是,有一種方法可以一次裝飾整個(gè)類:
Now, do not panic. This looks complicated, but this is the same logic:
現(xiàn)在,不要驚慌。 這看起來(lái)很復(fù)雜,但這是相同的邏輯:
Firstly, we leave the logging_decorator as is. It will be applied to all methods of a class.
首先,我們保持logging_decorator 。 它將應(yīng)用于類的所有方法。
Then we define a new decorator: log_all_class_methods. It is like a regular decorator but returns a class instead.
然后,我們定義一個(gè)新的裝飾器: log_all_class_methods 。 它就像一個(gè)普通的裝飾器,但是返回一個(gè)類。
The NewCls has a custom __getattribute__. For all calls to the original class, it will decorate the functions with the logging_decorator.
NewCls有一個(gè)自定義__getattribute__ 。 對(duì)于所有對(duì)原始類的調(diào)用,它將使用logging_decorator裝飾函數(shù)。
內(nèi)置裝飾器 (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:
您不僅可以定義自己的裝飾器,而且標(biāo)準(zhǔn)庫(kù)中也有一些裝飾器。 我將列出我工作最多的三個(gè)人:
@property — A decorator from built-ins that lets you define getters and setters for class properties.
@property property-內(nèi)置的裝飾器,可讓您定義類屬性的getter和setter。
@lru_cache — A decorator from the functools module. It memorizes function arguments and return values, which is handy for pure functions (like the factorial).
@lru_cache — functools模塊中的裝飾器。 它存儲(chǔ)函數(shù)參數(shù)和返回值,這對(duì)于純函數(shù)(例如factorial )非常方便。
@abstractmethod — A decorator from the abc module. Indicates that the method is abstract and implementation details are missing.
@abstractmethod —來(lái)自abc模塊的裝飾器。 表示該方法是抽象的,并且缺少實(shí)現(xiàn)細(xì)節(jié)。
結(jié)束語(yǔ) (Closing Notes)
Thank you for reading, I hope you liked my article. Stay subscribed for more Python content!
感謝您的閱讀,希望您喜歡我的文章。 請(qǐng)繼續(xù)訂閱更多Python內(nèi)容!
資源資源 (Resources)
PEP 318 — Decorators for Functions and Methods
PEP 318 —功能和方法的裝飾器
Higher-order functions and operations on callable objects
可調(diào)用對(duì)象的高階函數(shù)和操作
翻譯自: https://medium.com/better-programming/why-you-need-decorators-in-your-python-code-df12d43eac9c
總結(jié)
以上是生活随笔為你收集整理的为什么在Python代码中需要装饰器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 男生梦到很多蛇是什么征兆
- 下一篇: Python气流介绍