在其他函数python中传递函数作为参数

时间:2014-07-24 18:40:00

标签: python function

我有这些函数,并且我遇到错误,使用do_twice函数,但我在调试时遇到问题

#!/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))

调试器错误

:!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

3 个答案:

答案 0 :(得分:11)

问题是表达式print_twice(str)是通过使用print_twice调用str并获得返回的结果来评估的,*结果就是您作为参数传递的结果到do_four

您需要传递给do_four的是一个函数,在调用时会调用print_twice(str)

您可以手动构建此类功能:

def print_twice_str():
    print_twice(str)
do_four(print_twice_str)

或者你可以内联做同样的事情:

do_four(lambda: print_twice(str))

或者您可以使用高阶函数partial为您执行此操作:

from functools import partial
do_four(partial(print_twice, str))

partial的文档有一个很好的解释:

  

partial()用于部分函数应用程序,它“冻结”函数的参数和/或关键字的某些部分,从而产生具有简化签名的新对象。例如,partial()可用于创建一个行为类似于int()函数的调用,其中 base 参数默认为两个:[snip] basetwo = partial(int, base=2)


*如果您正在考虑“但我没有返回任何内容,那么None来自哪里?”:每个函数总是在Python中返回一个值。如果您没有告诉它返回什么,它将返回None

答案 1 :(得分:3)

do_four(print_twice(str))行在传递之前首先计算括号中的表达式。由于print_twice没有返回任何内容,因此假设None,并且它会被传递。

答案 2 :(得分:2)

现在print_twice正在返回None,这最终会作为参数传递给do_four。换句话说,您传递函数调用的结果而不是函数调用本身。

相反,您希望将该函数调用包装在lamda函数中,如下所示:

do_four(lambda: print_twice(str))

这会将实际的函数调用作为参数传递,而不是调用函数并传递结果。