Skip to content

Commit ec61cf4

Browse files
committed
Function parameters and varying numbers of parameters
1 parent 49c6b69 commit ec61cf4

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

concepts/decorators/about.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,61 @@ If we look inside our `wrapper()` function, we first see a call to the original
150150
This call will do exactly the same as if we had called the original function without the decoration to the function.
151151
Then we get a line that modifies this result.
152152
Finally we return the modified result, which is what we get when calling the function.
153+
154+
If we apply this decorator to a function which takes a single number and triples it, then we should get a function that sextuples our number.
155+
Lets see what happens:
156+
```py
157+
@double
158+
def triple(number):
159+
return number * 3
160+
```
161+
```py
162+
>>>triple(5)
163+
Traceback (most recent call last):
164+
File "<stdin>", line 1, in <module>
165+
TypeError: wrapper() takes 0 positional arguments but 1 was given
166+
```
167+
Unfortunately, we get an error.
168+
This happens because, as said earlier, python does not call the original function when you appear to call it.
169+
Python actually calls the function in the decorator, `wrapper()`, which does not have any parameters.
170+
171+
To rectify this, we can add a parameter to our `wrapper()` function.
172+
An updated `@double` decorator is shown below:
173+
```py
174+
def double(f):
175+
def wrapper(value):
176+
func_result = f(value)
177+
doubled = func_result * 2
178+
return doubled
179+
return wrapper
180+
```
181+
```py
182+
>>>triple(5)
183+
30
184+
```
185+
However, if we now call our function which took no parameters earlier, it will fail:
186+
```py
187+
>>>function6b()
188+
Traceback (most recent call last):
189+
File "<stdin>", line 1, in <module>
190+
TypeError: wrapper() mising 1 required positional argument: 'value'
191+
```
192+
It would also fail for any other number of parameters too.
193+
194+
Fortunately we can write decorators that don't care about the number of parameters a function may take by using the `*args` and `**kwargs` syntax.
195+
Here's an update `@double` decorator:
196+
```py
197+
def double(f):
198+
def wrapper(*args, **kwargs):
199+
func_result = f(*args, **kwargs)
200+
doubled = func_result * 2
201+
return doubled
202+
return wrapper
203+
```
204+
Now we should be to use this decorator on functions which accept zero, one, two or even one million (though we wouldn't recommend that many!) parameters:
205+
```py
206+
>>>triple(5)
207+
30
208+
>>>function6b()
209+
14
210+
```

0 commit comments

Comments
 (0)