2013-07-30 135 views
1
$ 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") 

我发现这个Declare function at end of file in Python

任何方式似乎有像包装开始另一个函数,这个包装必须包装的函数的声明之后被调用,这是不是一个出口。是否有更多优雅真python的方式?

+3

您链接的解决方案中的答案既是pythonic又是优雅。 –

+0

另一个重复的问题:http://stackoverflow.com/questions/1590608/is-it-possible-to-forward-declare-a-function-in-python – 2rs2ts

回答

4

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

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

任何技巧来排序的达到你想要的效果必须有延迟调用declared_after(),直到它被定义后,例如效果,在另一def块本身就是后来被称为封闭它。

1

一两件事你可以做的是在主函数封装的一切:

def main(): 
    declared_after() 

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

main() 

然而,问题依然存在,该功能必须在调用定义。这仅适用于因为main被称为AFTER declared_after而被定义。

0

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

通常的办法来解决,这是只是有一个main功能,所有的标准执行的事情发生:

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

def declared_after(): 
    pass 

main() 

然后,您可以还与__name__ == '__main__' idiom结合本作的功能只有当你执行直接执行模块:

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

def declared_after(): 
    pass 

if __name__ == '__main__': 
    main() 
2

您不能在Python中转发声明函数。这样做并没有什么意义,因为Python是动态输入的。你可以像这样做一些傻事,并期望它做什么?

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

很显然,你试图__call__int对象3.这绝对是愚蠢的。

你问你是否可以像在C/C++中那样转发声明。那么,你通常不会通过解释器运行C.但是,尽管Python是compiled to bytecode,但python3程序是一个解释器。

以编译语言进行前向声明是有意义的,因为您只是简单地建立一个符号及其类型,并且编译器可以多次运行代码来理解它。然而,当你使用一个解释器时,你通常不会有那么奢侈,因为你必须通过代码的其余部分来找到该前向声明的含义,并在完成之后再次运行它。

你可以,当然,做这样的事情:

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

但你实例化foo不过。一切都必须指向Python中的一个实际的现有对象。

虽然这不适用于defclass陈述。这些会创建一个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 

这可以防止任何从模块是否进口发生。