使用作为参数传入的函数对象定义函数

时间:2015-02-10 16:13:29

标签: python function object

我正在使用互联网教自己像python一样有用的东西。到目前为止,我一直在使用的资源是“Downey的Think python”和Lutz的“Learning Python”。我第一次被介绍给python这个关于计算机科学的Udacity计划,并且从现在开始自学。我是一个编码新手,这是我试图学习的第一种语言。

我的问题是唐尼在'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或其他任何东西注册这只是我和他互联网与python。 TIA

2 个答案:

答案 0 :(得分:1)

嗨,这是我最终实际工作的最终代码。

    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)

两个打印电话'在这里'和类型(f)被放入试图了解程序发生了什么并且不需要在那里,但我喜欢我的飞跃的提醒制作 - 所以他们留在。

答案 1 :(得分:0)

我认为你几乎就在那里。我认为问题在于您在方法中调用f。不要忘记 - 您已将函数作为f传递,而不是函数调用。因此,当您的f函数中有do_n时,它什么都不做。如果你做了f()它实际上会调用f(没有参数,可能允许也可能不允许),如果你f(n)可能更好,它应该调用print_string n 1}}作为参数。我嘲笑了一个小小的演示来让你前进:

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澄清。原始代码与原始帖子相同,但使用行

调用
do_n(print_string('test'),6)

问题在于print_string()功能正在进入do_n之前。由于print_string()函数只是打印它给出的(我假设)并且什么都不返回 - 你实际上是将None传递给do_n函数。

顺便说一句,并且说服自己在调用print_string之前评估do_n - 尝试对原作进行一次更改

do_n(print_string('test'),0)

您可能希望看不到任何内容,但实际上您会看到输出test,因为仍会调用print_string。

解决方案

要将函数传递给另一个函数,请传递其名称,但 使用任何括号或参数进行操作。这样,您传递的是函数对象,而不是调用该函数的结果。

你实际上是在你希望它做某事的接收函数中调用该函数(或者确实将它传递给另一个函数)。我上面的示例代码仍然有效。注意 - 我传入的print_string没有括号或参数。

这是一项强大的技巧 - 可能需要一点思考才能让你的头脑清醒,但这样做是值得的。根据经验 - 如果您看到一个没有任何括号的函数名称,它将作为函数对象传递。如果它后跟括号,则在那时进行评估。