[英]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 我有这些函数,并且我遇到错误,使用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))
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
. 问题是表达式
print_twice(str)
是通过使用str
调用print_twice
并获得返回的结果来评估的,*结果就是你作为do_four
的参数传递的do_four
。
What you need to pass to do_four
is a function that, when called, calls print_twice(str)
. 你需要传递给
do_four
是一个函数,当调用它时,调用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: 或者您可以使用高阶函数
partial
来为您执行此操作:
from functools import partial
do_four(partial(print_twice, str))
The documentation for partial
has a pretty nice explanation: partial
的文档有一个非常好的解释:
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.partial()
用于部分函数应用程序,它“冻结”函数的参数和/或关键字的某些部分,从而产生具有简化签名的新对象。 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)
例如,
partial()
可用于创建一个callable,其行为类似于int()
函数,其中base参数默认为2:[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. *如果您正在考虑“但我没有返回任何内容,那么
None
来自哪里?”:每个函数总是返回Python中的值。 If you don't tell it what to return, it returns None
. 如果您没有告诉它返回什么,它将返回
None
。
The line do_four(print_twice(str))
evaluates the expression in the brackets first before passing it. do_four(print_twice(str))
传递之前首先计算括号中的表达式。 Since print_twice doesn't return anything, None
is assumed, and that gets passed. 由于print_twice不返回任何内容,因此假定为
None
,并且会传递该内容。
Right now print_twice
is returning None
which is what ends up being passed to do_four
as a parameter. 现在
print_twice
返回None
,这最终作为参数传递给do_four
。 In other words, you are passing the result of the function call instead of the function call itself. 换句话说,您传递函数调用的结果而不是函数调用本身。
Instead you want to wrap that function call in a lamda function like this: 相反,你想在lamda函数中包装该函数调用,如下所示:
do_four(lambda: print_twice(str))
This will pass the actual function call as a parameter instead of calling the function and passing its result. 这将把实际的函数调用作为参数传递,而不是调用函数并传递其结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.