Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在Python中向前声明函数?_Python_Forward Declaration - Fatal编程技术网

是否可以在Python中向前声明函数?

是否可以在Python中向前声明函数?,python,forward-declaration,Python,Forward Declaration,是否可以在Python中向前声明函数?在声明列表之前,我想使用我自己的cmp函数对列表进行排序 print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)]) 我组织了我的代码,将cmp\u configs方法的定义放在调用之后。它失败,出现以下错误: NameError: name 'cmp_configs' is not defined 在使用cmp\U配置方法之前,是否有任何方法可以“声明”cmp\U配置

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

print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])
我组织了我的代码,将
cmp\u configs
方法的定义放在调用之后。它失败,出现以下错误:

NameError: name 'cmp_configs' is not defined
在使用cmp\U配置方法之前,是否有任何方法可以“声明”
cmp\U配置方法?这会让我的代码看起来更干净吗

我假设有些人会告诉我,我应该重新组织我的代码,这样我就不会有这个问题。然而,在某些情况下,这可能是不可避免的,例如在实现某些形式的递归时。如果你不喜欢这个例子,假设我有一个例子,在这个例子中,确实有必要向前声明一个函数

考虑在Python中需要向前声明函数的情况:

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

def eggs():
    if end_condition():
        return end_result()
    else:
        return spam()
其中,
end\u条件
end\u结果
已预先定义

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

“只要重新组织我的代码,这样我就不会有这个问题。”正确。容易做。总是有用的

您始终可以在函数引用之前提供该函数

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


看不出这怎么可能。请提供一个无法在使用前定义函数的地方的示例。

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

if __name__=="__main__":
   main()
def foo():
    bar()

def bar():
    foo()
那么,您可能不必担心“远期申报”之类的事情。你看,解释器将加载所有函数,然后启动main()函数。当然,也要确保所有导入都正确;-)


想想看,我从来没有听说过python中的“转发声明”之类的东西。。。但话说回来,我可能错了;-)

您可以做的是将调用包装成自己的函数

所以

foo()

def foo():
    print "Hi!"
会破裂,但是

def bar():
    foo()

def foo():
    print "Hi!"

bar()
会正常工作的

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


希望有帮助

如果您不想在函数使用之前定义它,而之后又无法定义它,那么在其他模块中定义它怎么样

从技术上讲,你还是先定义它,但它是干净的

您可以创建如下所示的递归:

if __name__=="__main__":
   main()
def foo():
    bar()

def bar():
    foo()
Python的函数是匿名的,就像值是匿名的一样,但它们可以绑定到名称

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


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

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

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

print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])
要么知道cmp_配置是什么,要么不知道。为了继续,你必须
了解cmp_配置。是否存在递归并不重要。

如果对cmp\u 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中没有类似于转发声明的东西。您只需确保在需要函数之前声明了它。 请注意,函数体在函数执行之前不会被解释

考虑以下示例:

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.

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

现在请稍候。在定义
cmp\u configs
之前,当您的模块到达示例中的print语句时,您希望它做什么

如果您使用print发布的问题真的试图表达如下内容:

fn = lambda mylist:"\n".join([str(bla)
                         for bla in sorted(mylist, cmp = cmp_configs)])
# 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]()
那么在执行此语句之前就不需要定义
cmp\u configs
,只需在代码中稍后定义它,一切都会好起来

现在,如果您试图引用
cmp\u configs
作为lambda参数的默认值,那么情况就不同了:

fn = lambda mylist,cmp_configs=cmp_configs : \
    "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])
现在,您需要在到达此行之前定义一个
cmp\u configs
变量

[编辑-下一部分结果不正确,因为编译函数时将分配默认参数值,即使稍后更改cmp_configs的值,也将使用该值。]

幸运的是,Python虽然非常适合类型,但它并不关心您定义为什么
cmp\u configs
,因此您只需在前面介绍以下语句:

cmp_configs = None

编译器会很高兴的。只要确保在调用
fn
之前声明真正的
cmp\u配置
,在Python中不能向前声明函数。如果您在定义函数之前执行了逻辑,那么您可能会遇到问题。将您的操作放在脚本末尾的
中,如果_uname_=='\uuuu main\uuuu'
(通过执行一个名为“main”的函数,如果它不是普通的函数),您的代码将更加模块化,如果需要,您将能够将其用作模块

另外,用生成器express(即,
print“\n”。join(str(bla)表示已排序的bla(mylist,cmp=cmp_configs))
)替换该列表理解

另外,不要使用已弃用的
cmp
。使用
并提供小于函数
print_lyrics() 
def print_lyrics():

    print("I'm a lumberjack, and I'm okay.")
    print("I sleep all night and I work all day.")

def repeat_lyrics():
    print_lyrics()
    print_lyrics()
repeat_lyrics()
I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.
I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.
I'm a lumberjack, and I'm okay.
I sleep all night and I work all day.
import test

if __name__=='__main__':
    test.func()
else:
    def func():
        print('Func worked')
# 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()
def foo(count):
    print("foo "+str(count))
    if(count>0):
        bar(count-1)

def bar(count):
    print("bar "+str(count))
    if(count>0):
        foo(count-1)

foo(3)
print("Finished.")
foo 3
bar 2
foo 1
bar 0
Finished.
bug(13)

def bug(count):
    print("bug never runs "+str(count))

print("Does not print this.")
Traceback (most recent call last):
  File "./test1.py", line 1, in <module>
    bug(13)
NameError: name 'bug' is not defined
def uncalled():
    wild_eyed_undefined_function()
    print("I'm not invoked!")

print("Only run this one line.")
Only run this one line.
if __name__ == '__main__': main()