Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing functions as arguments in other functions python

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
like image 788
miatech Avatar asked Sep 26 '26 06:09

miatech


1 Answers

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 the int() 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.

like image 174
abarnert Avatar answered Sep 27 '26 19:09

abarnert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!