是否有可能在Python中转发声明一个函数?

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

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

我已经组织了我的代码,在调用之后放置了cmp_configs方法的定义。 它失败,出现这个错误:

 NameError: name 'cmp_configs' is not defined 

在使用cmp_configs方法之前,有没有办法“声明” cmp_configs方法? 这将使我的代码看起来更清洁?

我想有些人会试图告诉我,我应该重新组织我的代码,使我没有这个问题。 但是,有些情况下,这可能是不可避免的,例如在执行某种forms的recursion时。 如果你不喜欢这个例子,假设我有一个真正需要转发声明一个函数的情况。

考虑一下在Python中向前声明一个函数是必要的:

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

其中end_conditionend_result已经被定义。

是唯一的解决scheme来重新组织的代码,总是把调用之前的定义?

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

从技术上讲,你仍然首先定义它,但它很干净。

你可以像下面这样创build一个recursion:

 def foo(): bar() def bar(): foo() 

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

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

你的问题不能解决,因为它就像要求得到一个尚未宣布的variables。

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

 if __name__=="__main__": main() 

那么你可能不必担心“前向声明”这样的事情。 你看,解释器会加载你所有的函数,然后开始你的main()函数。 当然,确保你所有的import都是正确的;-)

想想吧,我从来没有听说过python中的“前向声明”这样的东西…但是再一次,我可能是错的;-)

你可以做的是把调用包装成一个自己的函数。

以便

 foo() def foo(): print "Hi!" 

会打破,但是

 def bar(): foo() def foo(): print "Hi!" bar() 

将正常工作。

Python一般规则并不是应该在代码中定义更高的function(如在Pascal ),而是应该在使用之前定义它。

希望有所帮助。

如果对cmp_configs的调用在它自己的函数定义中,你应该没问题。 我会举一个例子。

 def a(): b() # b() hasn't been defined yet, but that's fine because at this point, we're not # actually calling it. We're just defining what should happen when a() is called. a() # This call fails, because b() hasn't been defined yet, # and thus trying to run a() fails. def b(): print "hi" a() # This call succeeds because everything has been defined. 

一般来说,把你的代码放在函数里(比如main())将会解决你的问题。 只需在文件末尾调用main()即可。

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

想象一下,你是Python解释器。 当你到达线路

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

要么你知道cmp_configs是什么,或者你不知道。 为了继续,你必须知道cmp_configs。 如果有recursion没有关系。

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. 

你可以认为一个函数体是另一个脚本,一旦你调用函数就会被解释。

有时候,一个algorithm最容易理解,从整体结构开始,深入细节。

你可以这样做,没有前向声明:

 def main(): make_omelet() eat() def make_omelet(): break_eggs() whisk() fry() def break_eggs(): for egg in carton: break(egg) # ... main() 

我很抱歉重振这个主题,但是这里没有讨论可能适用的策略。

使用reflection可以做类似于前向声明的事情。 例如让我们说你有一段代码,看起来像这样:

 # We want to call a function called 'foo', but it hasn't been defined yet. function_name = 'foo' # Calling at this point would produce an error # Here is the definition def foo(): bar() # Note that at this point the function is defined # Time for some reflection... globals()[function_name]() 

所以通过这种方式,我们已经确定了在实际定义之前我们要调用什么函数,实际上是一个前向声明。 在Python中,由于上面讨论的原因,语句globals()[function_name]()foo()相同,因为python必须在调用每个函数之前查找每个函数。 如果使用timeit模块来查看这两个语句如何比较,则它们具有完全相同的计算成本。

当然这里的例子是无用的,但是如果有一个需要执行一个函数的复杂结构,但是必须在之前声明(或者在结构上它没有什么意义),那么可以存储一个string尝试稍后调用该函数。

你不能在Python中转发声明一个函数。 如果你在定义函数之前执行了逻辑,反正你可能会遇到问题。 把你的行为放在脚本末尾的if __name__ == '__main__' (通过执行一个名字为“main”的函数,如果它不重要),你的代码将更加模块化,你就可以使用它作为一个模块,如果你需要的话。

另外,用一个生成器expression式来replace列表理解(例如,在已sorting的(mylist,cmp = cmp_configs))中打印“\ n”.join(str(bla)

另外,不要使用不推荐使用的cmp。 使用“键”并提供一个小于function。

“只是重新组织我的代码,使我没有这个问题。” 正确。 容易做到。 始终有效。

您可以在参考之前始终提供该function。

“但是,有些情况下,这可能是不可避免的,例如,当实施某种forms的recursion”

看不到这是甚至是远程可能的。 请提供一个在使用前无法定义function的例子。

现在等一下。 当你的模块到达你的例子中的print语句之前,在定义cmp_configs之前,你期望它做什么?

如果你使用print来发布一个问题,实际上是想expression如下的东西:

 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_configsvariables。

[编辑 – 这下一部分结果是不正确的,因为默认参数值将在编译函数时得到分配,即使您稍后更改cmp_configs的值,将使用该值。

幸运的是,Python是如此typescmp_configs ,不关心你定义为cmp_configs ,所以你可以只用这个语句:

 cmp_configs = None 

编译器会很高兴。 只要确保在调用fn之前声明真正的cmp_configs

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

然后,当你调用处理函数来调用你的函数时,它们将始终可用。

处理程序可以采用参数nameOfMethodToCall 。 然后使用一堆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)