是否有可能在Python中前向声明一个函数?我想在声明之前使用我自己的cmp函数对列表进行排序。

print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])

我把cmp_configs方法的定义放在调用之后。它会失败,报错如下:

NameError: name 'cmp_configs' is not defined

是否有任何方法在使用cmp_configs方法之前“声明”它?

有时候,很难重新组织代码来避免这个问题。例如,在实现某些形式的递归时:

def spam():
    if end_condition():
        return end_result()
    else:
        return eggs()

def eggs():
    if end_condition():
        return end_result()
    else:
        return spam()

其中end_condition和end_result已经在前面定义。

唯一的解决方案是重新组织代码并始终在调用之前放置定义吗?


当前回答

# declare a fake function (prototype) with no body
def foo(): pass

def bar():
    # use the prototype however you see fit
    print(foo(), "world!")

# define the actual function (overwriting the prototype)
def foo():
    return "Hello,"

bar()

输出:

Hello, world!

其他回答

如果您不想在使用函数之前定义它,并且在使用之后定义它是不可能的,那么在其他模块中定义它呢?

从技术上讲,您仍然先定义它,但它是干净的。

你可以创建一个像下面这样的递归:

def foo():
    bar()

def bar():
    foo()

Python的函数是匿名的,就像值是匿名的一样,但是它们可以绑定到一个名称。

在上面的代码中,foo()并不调用foo名称的函数,它调用的函数恰好在调用时绑定到foo名称。可以在其他地方重新定义foo,然后bar将调用新函数。

您的问题无法解决,因为这就像要求获得一个未声明的变量。

将调用包装到它自己的函数中,以便

foo()

def foo():
    print "Hi!"

会破碎,但

def bar():
    foo()

def foo():
    print "Hi!"

bar()

将正常工作。

Python中的一般规则是,函数应该在使用之前定义,这并不一定意味着它需要在代码中处于更高的位置。

“重新组织我的代码,这样我就不会有这个问题了。”正确的。很容易做到。总是工作。

您总是可以在引用函数之前提供该函数。

“然而,在某些情况下,这可能是不可避免的,例如在实现某些形式的递归时”

我看不出这有什么可能。请举例说明在使用之前不能定义函数的地方。

现在等一下。当您的模块到达示例中的print语句时,在定义cmp_configs之前,您到底希望它做什么?

如果你用print发布的问题实际上是想表达这样的东西:

fn = lambda mylist:"\n".join([str(bla)
                         for bla in sorted(mylist, cmp = cmp_configs)])

那么在执行这条语句之前就不需要定义cmp_configs了,只要在后面的代码中定义它就可以了。

现在如果你试图引用cmp_configs作为lambda参数的默认值,那么这是一个不同的故事:

fn = lambda mylist,cmp_configs=cmp_configs : \
    "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])

现在,您需要在到达这一行之前定义一个cmp_configs变量。

[EDIT -接下来的部分被证明是不正确的,因为默认参数值将在函数编译时被赋值,即使您稍后更改cmp_configs的值,该值也将被使用。]

幸运的是,Python是如此适应类型,并不关心你定义什么为cmp_configs,所以你可以用这句话开始:

cmp_configs = None

这样编译器就高兴了。只要确保在调用fn之前声明真正的cmp_configs即可。

不,我不相信有任何方法可以在Python中前向声明一个函数。

假设您是Python解释器。当你走到排队的时候

print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])

您可能知道cmp_configs是什么,也可能不知道。为了继续,你必须 知道cmp_configs。不管有没有递归。