简体   繁体   English

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

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM