是否有可能在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已经在前面定义。

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


当前回答

Python在技术上支持前向声明。

如果你定义了一个函数/类,然后将函数体设置为pass,那么它在全局表中将有一个空条目。

然后,您可以“重新定义”函数/类,以实现函数/类。

与c/c++前向声明不同的是,这不能在作用域外(即另一个文件)工作,因为它们有自己的“全局”命名空间

例子:

def foo(): pass

foo()

def foo(): print("FOOOOO")

foo()

两次都声明了Foo 然而,第一次调用foo时,它没有做任何事情,因为body只是传递 但是第二次调用foo。它执行新的打印体("FOOOOO")

但再一次。注意,这不会修复循环依赖关系。这是因为文件有自己的名称和自己的函数定义

示例2:


class bar: pass

print(bar)

这将打印<class '__main__。Bar '>,但如果它在另一个文件中声明,它将是<class 'otherfile.foo'>

我知道这篇文章很旧了,但我认为这个答案对任何在张贴多年后仍然找到这篇文章的人都是有用的

其他回答

如果你通过以下方式启动你的脚本:

if __name__=="__main__":
   main()

那么你可能就不必担心“向前声明”之类的事情了。你看,解释器会加载你所有的函数,然后启动你的main()函数。当然,也要确保所有的导入都是正确的;-)

仔细想想,我从来没有在python中听到过“前向声明”这样的东西……但话说回来,我可能错了;-)

在python中没有像前向声明这样的东西。您只需确保在需要函数之前声明了它。 注意,函数体在执行之前不会被解释。

考虑下面的例子:

def a():
   b() # won't be resolved until a is invoked.

def b(): 
   print "hello"

a() # here b is already defined so this line won't fail.

您可以认为函数体只是另一个脚本,在调用该函数后将对其进行解释。

在Python中不能前向声明函数。如果在定义函数之前已经执行了逻辑,那么无论如何都可能遇到问题。将你的动作放在脚本末尾的if __name__ == '__main__'中(通过执行一个你命名为“main”的函数,如果它不是平凡的),你的代码将更加模块化,如果你需要,你将能够将它作为一个模块使用。

同样,用生成器表达式替换该列表理解(即,打印"\n".join(str(bla) for bla in sorted(mylist, cmp=cmp_configs)))

另外,不要使用已弃用的cmp。使用键并提供小于函数。

有时,算法最容易自上而下地理解,从整体结构开始,深入到细节。

你可以在没有前向声明的情况下这样做:

def main():
  make_omelet()
  eat()

def make_omelet():
  break_eggs()
  whisk()
  fry()

def break_eggs():
  for egg in carton:
    break(egg)

# ...

main()

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

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

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

def foo():
    bar()

def bar():
    foo()

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

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

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