@@ -120,26 +120,27 @@ The inner function may then return the original function argument.
120120Following is an example of a decorator being used for validation:
121121
122122``` python
123- >> > def my_validator (func ):
124- ... def my_wrapper (world ):
125- ... print (f " Entering { func.__name__ } with { world} argument " )
126- ... if (" Pluto" == world):
127- ... print (" Pluto is not a planet!" )
128- ... else :
129- ... return func(world)
130- ... return my_wrapper
131- ...
132- ... @ my_validator
133- ... def my_func (planet ):
134- ... print (f " Hello, { planet} ! " )
135- ...
136- >> > my_func(" World" )
137- Entering my_func with World argument
138- Hello, World!
139- ...
140- >> > my_func(" Pluto" )
141- Entering my_func with Pluto argument
142- Pluto is not a planet!
123+ def my_validator (func ):
124+ def my_wrapper (world ):
125+ print (f " Entering { func.__name__ } with { world} argument " )
126+
127+ if (world == " Pluto" ):
128+ print (" Pluto is not a planet!" )
129+ else :
130+ return func(world)
131+ return my_wrapper
132+
133+ @my_validator
134+ def my_func (planet ):
135+ print (f " Hello, { planet} ! " )
136+
137+ my_func(" World" )
138+ # -> Entering my_func with World argument
139+ # -> Hello, World!
140+
141+ my_func(" Pluto" )
142+ # -> Entering my_func with Pluto argument
143+ # -> Pluto is not a planet!
143144```
144145
145146On the first line, we have the definition for the decorator with its ` func ` argument.
@@ -148,7 +149,7 @@ Since the _inner function_ wraps the decorator's `func` argument, it is passed t
148149Note that the wrapper doesn't have to use the same name for the argument that was defined in ` func ` .
149150The original function uses ` planet ` and the decorator uses ` world ` , and the decorator still works.
150151
151- The inner function returns either ` func ` or, if ` planet ` equals ` Pluto ` , it will print that Pluto is not a planet.
152+ The inner function returns either ` func ` or, if ` world ` equals " Pluto" , it will print that Pluto is not a planet.
152153It could be coded to raise a ` ValueError ` instead.
153154So, the inner function wraps ` func ` , and returns either ` func ` or does something that substitutes what ` func ` would do.
154155The decorator returns its _ inner function_ .
@@ -162,19 +163,20 @@ Decorators can be written for functions that take an arbitrary number of argumen
162163Following is an example of a decorator for a function that takes an arbitrary number of arguments:
163164
164165``` python
165- >> > def double (func ):
166- ... def wrapper (* args , ** kwargs ):
167- ... return func(* args, ** kwargs) * 2
168- ... return wrapper
169- ...
170- ... @ double
171- ... def add (* args ):
172- ... return sum (args)
173- ...
174- >> > print (add(2 , 3 , 4 ))
175- 18
176- >> > print (add(2 , 3 , 4 , 5 , 6 ))
177- 40
166+ def double (func ):
167+ def wrapper (* args , ** kwargs ):
168+ return func(* args, ** kwargs) * 2
169+ return wrapper
170+
171+ @double
172+ def add (* args ):
173+ return sum (args)
174+
175+ print (add(2 , 3 , 4 ))
176+ # ->18
177+
178+ print (add(2 , 3 , 4 , 5 , 6 ))
179+ # ->40
178180```
179181
180182This works for doubling the return value from the function argument.
@@ -185,24 +187,25 @@ If we want to triple, quadruple, etc. the return value, we can add a parameter t
185187Following is an example of a decorator that can be configured to multiply the decorated function's return value by an arbitrary amount:
186188
187189``` python
188- >> > def multi (factor = 1 ):
189- ... if (factor == 0 ):
190- ... raise ValueError (" factor must not be 0" )
191- ...
192- ... def outer_wrapper (func ):
193- ... def inner_wrapper (* args , ** kwargs ):
194- ... return func(* args, ** kwargs) * factor
195- ... return inner_wrapper
196- ... return outer_wrapper
197- ...
198- ... @ multi(factor = 3 )
199- ... def add (* args ):
200- ... return sum (args)
201- ...
202- >> > print (add(2 , 3 , 4 ))
203- 27
204- >> > print (add(2 , 3 , 4 , 5 , 6 ))
205- 60
190+ def multi (factor = 1 ):
191+ if factor == 0 :
192+ raise ValueError (" factor must not be 0" )
193+
194+ def outer_wrapper (func ):
195+ def inner_wrapper (* args , ** kwargs ):
196+ return func(* args, ** kwargs) * factor
197+ return inner_wrapper
198+ return outer_wrapper
199+
200+ @multi (factor = 3 )
201+ def add (* args ):
202+ return sum (args)
203+
204+ print (add(2 , 3 , 4 ))
205+ # ->27
206+
207+ print (add(2 , 3 , 4 , 5 , 6 ))
208+ # ->60
206209```
207210
208211The first lines validate that ` factor ` is not ` 0 ` .
@@ -215,27 +218,29 @@ The outer wrapper returns the inner wrapper, and the decorator returns the outer
215218Following is an example of a parameterized decorator that controls whether it validates the argument passed to the original function:
216219
217220``` python
218- >> > def check_for_pluto (check = True ):
219- ... def my_validator (func ):
220- ... def my_wrapper (world ):
221- ... print (f " Entering { func.__name__ } with { world} argument " )
222- ... if (check and " Pluto" == world):
223- ... print (" Pluto is not a planet!" )
224- ... else :
225- ... return func(world)
226- ... return my_wrapper
227- ... return my_validator
228- ...
229- ... @ check_for_pluto(check = False )
230- ... def my_func (planet ):
231- ... print (f " Hello, { planet} ! " )
232- ...
233- >> > my_func(" World" )
234- Entering my_func with World argument
235- Hello, World!
236- >> > my_func(" Pluto" )
237- Entering my_func with Pluto argument
238- Hello, Pluto!
221+ def check_for_pluto (check = True ):
222+ def my_validator (func ):
223+ def my_wrapper (world ):
224+ print (f " Entering { func.__name__ } with { world} argument " )
225+ if check and world == " Pluto" :
226+ print (" Pluto is not a planet!" )
227+ else :
228+ return func(world)
229+
230+ return my_wrapper
231+ return my_validator
232+
233+ @check_for_pluto (check = False )
234+ def my_func (planet ):
235+ print (f " Hello, { planet} ! " )
236+
237+ my_func(" World" )
238+ # -> Entering my_func with World argument
239+ # -> Hello, World!
240+
241+ my_func(" Pluto" )
242+ # -> Entering my_func with Pluto argument
243+ # -> Hello, Pluto!
239244```
240245
241246This allows for easy toggling between checking for ` Pluto ` or not, and is done without having to modify ` my_func ` .
0 commit comments