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

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


当前回答

一种方法是创建处理程序函数。尽早定义处理程序,并将处理程序放在需要调用的所有方法的下面。

然后,当您调用处理程序方法来调用函数时,它们将始终可用。

处理程序可以接受一个名为ofmethodtocall的参数。然后使用一堆if语句来调用正确的方法。

这将解决你的问题。

def foo():
    print("foo")
    #take input
    nextAction=input('What would you like to do next?:')
    return nextAction

def bar():
    print("bar")
    nextAction=input('What would you like to do next?:')
    return nextAction

def handler(action):
    if(action=="foo"):
        nextAction = foo()
    elif(action=="bar"):
        nextAction = bar()
    else:
        print("You entered invalid input, defaulting to bar")
        nextAction = "bar"
    return nextAction

nextAction=input('What would you like to do next?:')

while 1:
    nextAction = handler(nextAction)

其他回答

现在等一下。当您的模块到达示例中的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在技术上支持前向声明。

如果你定义了一个函数/类,然后将函数体设置为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'>

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

导入文件本身。假设文件名为test.py:

import test

if __name__=='__main__':
    test.func()
else:
    def func():
        print('Func worked')

Python不支持前向声明,但常见的解决方法是在脚本/代码的末尾使用以下条件:

if __name__ == '__main__': main()

这样,它将首先读取整个文件,然后计算condition并调用main()函数,该函数将能够调用任何前向声明的函数,因为它已经首先读取了整个文件。此条件利用特殊变量__name__,当我们从当前文件运行Python代码时,该变量返回__main__值(当代码作为模块导入时,__name__返回模块名)。

一种方法是创建处理程序函数。尽早定义处理程序,并将处理程序放在需要调用的所有方法的下面。

然后,当您调用处理程序方法来调用函数时,它们将始终可用。

处理程序可以接受一个名为ofmethodtocall的参数。然后使用一堆if语句来调用正确的方法。

这将解决你的问题。

def foo():
    print("foo")
    #take input
    nextAction=input('What would you like to do next?:')
    return nextAction

def bar():
    print("bar")
    nextAction=input('What would you like to do next?:')
    return nextAction

def handler(action):
    if(action=="foo"):
        nextAction = foo()
    elif(action=="bar"):
        nextAction = bar()
    else:
        print("You entered invalid input, defaulting to bar")
        nextAction = "bar"
    return nextAction

nextAction=input('What would you like to do next?:')

while 1:
    nextAction = handler(nextAction)