2
$ cat  declare_funcs.py
#!/usr/bin/python3

def declared_after():
        print("good declared after")

declared_after()

$ python3 declare_funcs.py
good declared after

更改通话地点:

$ cat  declare_funcs.py
#!/usr/bin/python3

declared_after()

def declared_after():
        print("good declared after")

$ python3 declare_funcs.py
Traceback (most recent call last):
  File "declare_funcs.py", line 4, in <module>
    declared_after()
NameError: name 'declared_after' is not defined

有没有办法像在 C/C++ 中那样只声明函数的标题?

例如:

#!/usr/bin/python3

def declared_after() # declaration about defined function 

declared_after()

def declared_after():
        print("good declared after")

在 Python 的文件末尾找到了这个 Declare 函数

无论如何,开头都会出现另一个函数,例如包装器,并且必须在声明包装函数后调用此包装器,这不是退出。有没有更优雅 的 true-python 方式?

4

4 回答 4

5

您不能在 Python 中前向声明函数。这样做没有多大意义,因为 Python 是动态类型的。你可以做一些像这样愚蠢的事情,期望它会做什么?

foo = 3
foo()
def foo():
    print "bar"

显然,您正在尝试__call__int对象设为 3。这绝对是愚蠢的。

您问是否可以像在 C/C++ 中一样进行前向声明。好吧,您通常不会通过解释器运行 C。然而,虽然 Python 被编译为 bytecode,但该python3程序是一个解释器。

编译语言中的前向声明是有意义的,因为您只是建立一个符号及其类型,编译器可以多次运行代码以理解它。但是,当您使用解释器时,您通常无法享受这种奢侈,因为您必须运行其余代码才能找到该前向声明的含义,并在完成后再次运行它。

当然,您可以执行以下操作:

foo = lambda: None
foo()
def foo():
    print "bar"

但是你仍然实例化foo了。一切都必须指向 Python 中实际存在的对象。

但是,这不适用于deforclass语句。这些创建了一个functionclass对象,但它们还没有执行里面的代码。因此,您有时间在它们的代码运行之前实例化它们内部的东西。

def foo():
    print bar()
# calling foo() won't work yet because you haven't defined bar()
def bar():
    return "bar"
# now it will work

不同之处在于您只需function使用变量名称创建对象foobar分别表示它们。您现在可以通过这些变量名称来引用这些对象。

关于 Python 通常被解释的方式(在 CPython 中),您应该确保在模块中不执行任何代码,除非它们作为主程序运行,或者除非您希望它们在导入时执行某些操作(很少见,但有效的情况下)。您应该执行以下操作:

  1. 将要执行的代码放入函数和类定义中。
  2. 除非代码只能在主程序中执行,否则将其放在另一个模块中。
  3. 用于if __name__ == "__main__":创建仅当程序是主程序时才会执行的代码块。

事实上,你应该在所有模块中做第三个。您可以简单地将其写在您不想作为主程序运行的每个文件的底部:

if __name__ = "__main__":
    pass

如果模块被导入,这可以防止任何事情发生。

于 2013-07-30T17:45:25.330 回答
4

Python 不是这样工作的。与文件的def其余内容一起按顺序执行,从上到下。在定义为可调用对象(例如函数)之前,您不能调用它,即使您有一个替代可调用对象,它也不会包含您要查找的代码。

当然,这并不意味着代码在执行开始之前没有被编译——事实上,它是。但实际上是在def执行时declared_after分配了def块内的代码,而不是之前。

您为达到您想要的效果而采用的任何技巧都必须具有将调用延迟到declared_after()定义之后的效果,例如,通过将其封闭在另一个def稍后调用的块中。

于 2013-07-30T17:17:03.217 回答
4

您可以做的一件事是将所有内容都包含在 main 函数中:

def main():
    declared_after()

def declared_after():
    print("good declared after")

main()

但是,重点仍然是必须在调用之前定义函数。这仅有效,因为在定义main之后调用。declared_after

于 2013-07-30T17:22:12.253 回答
0

正如 zigg 所写,Python 文件是按照从上到下的顺序执行的,所以即使你之前可以“声明”变量,实际的函数体也只会在函数被调用后到达那里。

解决这个问题的通常方法是只使用一个main函数,所有标准执行的东西都会发生:

def main ():
    # do stuff
    declared_after();

def declared_after():
    pass

main()

然后,您还可以将其与__name__ == '__main__'习语结合使用,使函数仅在您直接执行模块时执行:

def main ():
    # do stuff
    declared_after();

def declared_after():
    pass

if __name__ == '__main__':
    main()
于 2013-07-30T17:22:24.987 回答