使用作为参数传入的函数对象定义函数
Defining function with function object passed in as argument
我正在使用互联网自学一些有用的东西,例如 python。到目前为止我一直在使用的资源是 Downey 的 'Think python' 和 Lutz 的 'Learning Python'。我第一次接触 python Udacity 计算机科学项目,并从现在开始自学。我是编码新手,这是我尝试学习的第一门语言。
我的问题是 Downey 在 'think python' 中提出的一个问题,它正在定义一个函数,该函数将函数对象作为其参数之一以及数字 n。
在递归编程章节介绍过,一直给我养小猫。
到目前为止我的代码:
def print_string(s):
print (s)
return
def do_n(f , n):
if n <=0:
return
f
do_n(f, n-1)
现在我一直在尝试使用一个名为 print_string 的简单预定义打印函数,该函数接受参数。
我将脚本保存在一个名为 recursive.py 的文件中,并在 IDLE 中将其保存为 运行 然后在 运行 之后,我使用以下 do_n 调用 do_n (print_string('test'), 6)
我希望打印示例字符串 'test' 6
次,但它只打印一次。似乎没有递归。
我做错了什么?任何帮助将不胜感激,因为我真的负担不起注册 Udacity 或其他任何东西这只是我和互联网 vs python。 TIA
我想你快到了。我认为问题在于您在方法中调用 f
。别忘了 - 您传入的是 函数 作为 f
,而不是 函数调用 。因此,当您在 do_n
函数中包含 f
时,它什么都不做。如果你做了 f()
它实际上会调用 f (没有参数,可能允许也可能不允许)而且,如果你做了 f(n)
它应该调用 print_string
和 n
作为参数。我模拟了一个小演示来帮助您:
def print_string(arg1=''):
# mimicing your "pre-defined" function
# Note I've put a default value in arg1 so that you
# can call it without an argument to illustrate the priciple
print(arg1)
def do_n(f , n):
if n <=0:
return
f('test') # This is the line that was close, but not quite right
do_n(f, n-1)
do_n(print_string,10)
* 编辑 *
回应编辑中的 OP 说明。原始代码与原始 post 相同,但使用行
调用
do_n(print_string('test'),6)
问题在于 print_string()
函数在您输入 do_n
之前就已存在。由于 print_string()
函数只是打印它给出的内容(我假设)而 returns 什么都没有 - 你实际上是将 None
传递给 do_n
函数。
顺便说一句,让自己相信 print_string
在 do_n
被调用之前正在被评估 - 尝试对您的原始内容进行一次更改以说
do_n(print_string('test'),0)
您可能希望什么也看不到,但实际上您会看到输出 test
,因为 print_string 仍在调用。
解决方案
要将一个函数传递给另一个函数,您需要传递它的名称,但不要在它后面跟任何括号或参数。这样,您传递的是函数对象,而不是调用该函数的结果。
您实际上是从接收函数中调用该函数(或确实将其传递给另一个函数),您希望它执行某些操作。我上面的示例代码仍然有效。注意 - 我传入的 print_string
没有括号或参数。
这是一项强大的技术 - 可能需要花点时间思考才能让您头脑清醒,但这样做是值得的。作为一个经验法则——如果你看到一个函数名后面没有任何括号,它被作为一个函数对象传递。如果它后面有方括号,那么它正在评估。
嗨,这是我最终得到的实际有效的最终代码。
def print_string():
print ('result')
return
def do_n(f, n):
if n <=0:
return
print(type(f))
f()
print('been here')
do_n(f, n-1)
do_n(print_string, 6)
两个 print 调用 'been here' 和 type(f) 是为了尝试理解程序正在发生的事情,不需要在那里,但我喜欢飞跃的提醒我做到了 - 所以他们会留下来。
我正在使用互联网自学一些有用的东西,例如 python。到目前为止我一直在使用的资源是 Downey 的 'Think python' 和 Lutz 的 'Learning Python'。我第一次接触 python Udacity 计算机科学项目,并从现在开始自学。我是编码新手,这是我尝试学习的第一门语言。
我的问题是 Downey 在 'think python' 中提出的一个问题,它正在定义一个函数,该函数将函数对象作为其参数之一以及数字 n。
在递归编程章节介绍过,一直给我养小猫。
到目前为止我的代码:
def print_string(s):
print (s)
return
def do_n(f , n):
if n <=0:
return
f
do_n(f, n-1)
现在我一直在尝试使用一个名为 print_string 的简单预定义打印函数,该函数接受参数。
我将脚本保存在一个名为 recursive.py 的文件中,并在 IDLE 中将其保存为 运行 然后在 运行 之后,我使用以下 do_n 调用 do_n (print_string('test'), 6)
我希望打印示例字符串 'test' 6
次,但它只打印一次。似乎没有递归。
我做错了什么?任何帮助将不胜感激,因为我真的负担不起注册 Udacity 或其他任何东西这只是我和互联网 vs python。 TIA
我想你快到了。我认为问题在于您在方法中调用 f
。别忘了 - 您传入的是 函数 作为 f
,而不是 函数调用 。因此,当您在 do_n
函数中包含 f
时,它什么都不做。如果你做了 f()
它实际上会调用 f (没有参数,可能允许也可能不允许)而且,如果你做了 f(n)
它应该调用 print_string
和 n
作为参数。我模拟了一个小演示来帮助您:
def print_string(arg1=''):
# mimicing your "pre-defined" function
# Note I've put a default value in arg1 so that you
# can call it without an argument to illustrate the priciple
print(arg1)
def do_n(f , n):
if n <=0:
return
f('test') # This is the line that was close, but not quite right
do_n(f, n-1)
do_n(print_string,10)
* 编辑 *
回应编辑中的 OP 说明。原始代码与原始 post 相同,但使用行
调用do_n(print_string('test'),6)
问题在于 print_string()
函数在您输入 do_n
之前就已存在。由于 print_string()
函数只是打印它给出的内容(我假设)而 returns 什么都没有 - 你实际上是将 None
传递给 do_n
函数。
顺便说一句,让自己相信 print_string
在 do_n
被调用之前正在被评估 - 尝试对您的原始内容进行一次更改以说
do_n(print_string('test'),0)
您可能希望什么也看不到,但实际上您会看到输出 test
,因为 print_string 仍在调用。
解决方案
要将一个函数传递给另一个函数,您需要传递它的名称,但不要在它后面跟任何括号或参数。这样,您传递的是函数对象,而不是调用该函数的结果。
您实际上是从接收函数中调用该函数(或确实将其传递给另一个函数),您希望它执行某些操作。我上面的示例代码仍然有效。注意 - 我传入的 print_string
没有括号或参数。
这是一项强大的技术 - 可能需要花点时间思考才能让您头脑清醒,但这样做是值得的。作为一个经验法则——如果你看到一个函数名后面没有任何括号,它被作为一个函数对象传递。如果它后面有方括号,那么它正在评估。
嗨,这是我最终得到的实际有效的最终代码。
def print_string():
print ('result')
return
def do_n(f, n):
if n <=0:
return
print(type(f))
f()
print('been here')
do_n(f, n-1)
do_n(print_string, 6)
两个 print 调用 'been here' 和 type(f) 是为了尝试理解程序正在发生的事情,不需要在那里,但我喜欢飞跃的提醒我做到了 - 所以他们会留下来。