I have these functions, and I'm getting errors, with the do_twice functions, but I'm having problems debugging it
#!/usr/bin/python
#functins exercise 3.4
def do_twice(f):
f()
f()
def do_four(f):
do_twice(f)
do_twice(f)
def print_twice(str):
print str + 'one'
print str + 'two'
str = 'spam'
do_four(print_twice(str))
debugger errors
:!python 'workspace/python/functions3.4.py'
spamone
spamtwo
Traceback (most recent call last):
File "workspace/python/functions3.4.py", line 18, in <module>
do_four(print_twice(str))
File "workspace/python/functions3.4.py", line 9, in do_four
do_twice(f)
File "workspace/python/functions3.4.py", line 5, in do_twice
f()
TypeError: 'NoneType' object is not callable
shell returned 1
The problem is that the expression print_twice(str) is evaluated by calling print_twice with str and getting the result that you returned,* and that result is what you're passing as the argument to do_four.
What you need to pass to do_four is a function that, when called, calls print_twice(str).
You can build such a function manually:
def print_twice_str():
print_twice(str)
do_four(print_twice_str)
Or you can do the same thing inline:
do_four(lambda: print_twice(str))
Or you can use the higher-order function partial to do it for you:
from functools import partial
do_four(partial(print_twice, str))
The documentation for partial has a pretty nice explanation:
The
partial()is used for partial function application which “freezes” some portion of a function’s arguments and/or keywords resulting in a new object with a simplified signature. For example,partial()can be used to create a callable that behaves like theint()function where the base argument defaults to two: [snip]basetwo = partial(int, base=2)
* If you're thinking "But I didn't return anything, so where does that None come from?": Every function always returns a value in Python. If you don't tell it what to return, it returns None.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With