You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: concepts/decorators/about.md
+15-21Lines changed: 15 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,7 @@
3
3
Decorators are functions that take another function as an argument for the purpose of extending or replacing the behavior of the passed-in function.
4
4
If function `A` is a decorator, and function `B` is its argument, then function `A` modifies, extends or replaces function `B`'s **behavior**_without modifying_ function `B`'s code.
5
5
We say that the decorator function `A`_wraps_ function `B`.
6
-
While we talk about "modifying" behavior, the wrapped function is _not actually changed_.
6
+
While we talk about "modifying" behavior, the wrapped function is _not actually changed_.
7
7
Behavior is either added _around_ the wrapped function (_and what it returns_), or the wrapped function's behavior is _substituted_ for some other behavior.
8
8
9
9
## A Decorator is a Higher-Order Function
@@ -31,7 +31,7 @@ def decorated_function2():
31
31
pass
32
32
```
33
33
34
-
If a decorator has defined default arguments, you must use parenthesis in the `@decorator()` call for the decorator to work:
34
+
If a decorator has defined default arguments, you must use parenthesis in the `@decorator()` call for the decorator to work:
35
35
36
36
```python
37
37
@decorator_with_default_arg()
@@ -78,14 +78,13 @@ A simple decorator - one that simply returns its wrapped function - can be writt
78
78
```python
79
79
>>>defdo_nothing(func):
80
80
...return func
81
-
...
81
+
...
82
82
...@do_nothing
83
83
...deffunction4():
84
84
...return4
85
-
...
85
+
...
86
86
>>>print(function4())
87
87
4
88
-
89
88
```
90
89
91
90
A decorator may only add side effects, such as additional information used for logging:
@@ -94,15 +93,14 @@ A decorator may only add side effects, such as additional information used for l
94
93
>>>defmy_logger(func):
95
94
...print(f"Entering {func.__name__}")
96
95
...return func
97
-
...
96
+
...
98
97
...@my_logger
99
98
...defmy_func():
100
99
...print("Hello")
101
-
...
100
+
...
102
101
>>> my_func()
103
102
Entering my_func
104
103
Hello
105
-
106
104
```
107
105
108
106
A decorator does not return itself.
@@ -130,19 +128,18 @@ Following is an example of a decorator being used for validation:
130
128
...else:
131
129
...return func(world)
132
130
...return my_wrapper
133
-
...
131
+
...
134
132
...@my_validator
135
133
...defmy_func(planet):
136
134
...print(f"Hello, {planet}!")
137
-
...
135
+
...
138
136
>>> my_func("World")
139
137
Entering my_func with World argument
140
138
Hello, World!
141
139
...
142
140
>>> my_func("Pluto")
143
141
Entering my_func with Pluto argument
144
142
Pluto isnot a planet!
145
-
146
143
```
147
144
148
145
On the first line, we have the definition for the decorator with its `func` argument.
@@ -169,16 +166,15 @@ Following is an example of a decorator for a function that takes an arbitrary nu
169
166
...defwrapper(*args, **kwargs):
170
167
...return func(*args, **kwargs) *2
171
168
...return wrapper
172
-
...
169
+
...
173
170
...@double
174
171
...defadd(*args):
175
172
...returnsum(args)
176
-
...
173
+
...
177
174
>>>print(add(2, 3, 4))
178
175
18
179
176
>>>print(add(2, 3, 4, 5, 6))
180
177
40
181
-
182
178
```
183
179
184
180
This works for doubling the return value from the function argument.
@@ -192,22 +188,21 @@ Following is an example of a decorator that can be configured to multiply the de
192
188
>>>defmulti(factor=1):
193
189
...if (factor ==0):
194
190
...raiseValueError("factor must not be 0")
195
-
...
191
+
...
196
192
...defouter_wrapper(func):
197
193
...definner_wrapper(*args, **kwargs):
198
194
...return func(*args, **kwargs) * factor
199
195
...return inner_wrapper
200
196
...return outer_wrapper
201
-
...
197
+
...
202
198
...@multi(factor=3)
203
199
...defadd(*args):
204
200
...returnsum(args)
205
-
...
201
+
...
206
202
>>>print(add(2, 3, 4))
207
203
27
208
204
>>>print(add(2, 3, 4, 5, 6))
209
205
60
210
-
211
206
```
212
207
213
208
The first lines validate that `factor` is not `0`.
@@ -230,18 +225,17 @@ Following is an example of a parameterized decorator that controls whether it va
230
225
...return func(world)
231
226
...return my_wrapper
232
227
...return my_validator
233
-
...
228
+
...
234
229
...@check_for_pluto(check=False)
235
230
...defmy_func(planet):
236
231
...print(f"Hello, {planet}!")
237
-
...
232
+
...
238
233
>>> my_func("World")
239
234
Entering my_func with World argument
240
235
Hello, World!
241
236
>>> my_func("Pluto")
242
237
Entering my_func with Pluto argument
243
238
Hello, Pluto!
244
-
245
239
```
246
240
247
241
This allows for easy toggling between checking for `Pluto` or not, and is done without having to modify `my_func`.
0 commit comments