2010-06-06 24 views
19

我是新来的Python因此如果问题太基本的:)订单执行和编码的风格在Python

我已阅读,Python是从顶部执行请不要火焰我。

如果是这样的话,为什么程序是这样的:

def func2(): 
    pass 

def func1(): 
    func2() 

def func(): 
    func1() 

if __name__ == '__main__': 
    func() 

所以从我所看到的,主要功能发生在最后的,其他功能都堆积在它的上面。

我说错了吗?如果否,为什么主函数或函数定义不是从上到下写的?

编辑:我问,为什么我不能做到这一点:

if __name__ == '__main__': 
    func() 

def func1(): 
    func2() 

这不是自然的秩序?你继续在底部添加东西,因为它是从上到下执行的。

+0

这与无序执行无关。请参阅http://en.wikipedia.org/wiki/Out-of-order_execution – 2010-06-06 17:42:37

回答

22

def只是创建功能。除了解析语法并将函数与这些名称绑定之外,不执行任何代码。

if是实际执行的第一位代码。如果你先把它放好,并在定义它之前调用一个函数,那么结果就是一个NameError。因此,您需要在定义函数之后将其放入。

请注意,这不同于PHP或JavaScript,其中函数被'悬挂' - 任何函数定义在处理和解析之前都会被处理。在PHP和JavaScript中,执行你所说的并且在源代码中定义函数比调用它们的位置是完全合法的。 (JS中的一个细节是定义了像function(){}这样的函数,而像var func1=function(){};这样定义的函数不是,我不知道它如何与PHP 5.3中的匿名函数一起工作)。

请参阅此处,cat()将正确打印,并且yip()会给您一个NameError,因为解析器在您调用它时没有得到yip()的定义。

def cat(): 
    print 'meowin, yo' 

cat() 

yip() 

def yip(): 
    print 'barkin, yall' 

meowin, yo
Traceback (most recent call last):
File "cat.py", line 5, in
yip()
NameError: name 'yip' is not defined

0

def语句只是定义一个函数 - 它们实际上并没有运行它,直到函数被调用。因此,为什么它们通常在任何代码使用它们之前都会出现 - 它们将函数设置为将来使用。

有没有硬性要求是def声明任何事情之前到来,这只是相当普遍把__main__代码在底部(除其他事项外,它明确什么是在该节的,哪些不是,因为下面的东西if是该部分的一部分)。它也确保你想从该部分调用的任何东西已经是def'd。

0

的确,约定是将“main”函数放在文件末尾的“if __name__ == '__main__'”语句之上。我认为这是因为我们通常希望功能靠近他们的呼叫站点。

至于调用函数上方的被调用函数,我认为这只是重构的结果。至少在我的情况下,我倾向于编写一个函数,然后取出一些代码放入子函数中,这些子函数放在顶部以便我可以看得更清楚。

这只是代码组织的一种原始形式。如果有更强大的内聚单元,我会试图将这些功能放到他们自己的模块中。

1

if __name__ == "__main__"部分在最后,因为大概无论您的主要功能是否需要脚本中的所有其他定义。如果有其他函数定义低于主要块,那么它们将不可能在那里被使用,因为在那一点上他们还没有被解释者看到。

+2

只要func1已被_defined_ func2调用_called_,您就可以从func2调用func1。 – Weeble 2010-06-06 17:26:10

+0

注意到,删除。 – detly 2010-06-06 17:35:52

17

Python从上到下执行,但执行“def”块不会立即执行包含的代码。相反,它使用当前范围中的给定名称创建一个函数对象。考虑Python文件就像你的例子:

def func2(): 
    print "func2" 

def func1(): 
    func2() 

def func(): 
    func1() 

if __name__ == '__main__': 
    func() 

会发生什么事时,这个脚本执行如下:

首先,在全球范围内创建函数对象并将其绑定到名为“FUNC2” 。然后创建一个函数对象并绑定到全局范围中的名称“func1”。然后一个叫做“func”。然后执行“if”语句,条件成立并执行“func()”语句。此时“func”是在全局范围内找到的函数对象,因此它被调用并且其代码运行。该代码包含“func1()”语句,该语句已解析为调用“func1”函数,依此类推。

如果你把“if”语句放在顶部,那么当它执行的时候,还没有任何用“func”这个名字定义的东西,所以你会得到一个错误。重要的是,“def”语句本身就是一个被执行的语句。它不像其他一些语言中的定义是一种单独的声明而没有执行的顺序。

还要注意,只要“if __name__ ...”位在文件的末尾,其他声明的顺序并不重要,因为当它们中的任何一个被调用时的“def”将会被执行。

+0

这个顺序在C语言中很常见,即使在其他函数定义中,函数也必须在使用之前进行声明。人们使用该命令来避免需要前向声明。我并不认为这在Python中是必要的,但我仍然是出于习惯。 – phkahler 2010-06-06 17:43:03

+0

为什么**如果__name__ =='__main __':**为真?请解释。我投了! – 2017-06-04 19:18:56

+1

@YanKhonski查看https://stackoverflow.com/questions/419163/what-does-if-name-main-do – Weeble 2017-06-06 08:16:30

3

Python通常会自上而下处理命令。但是,函数调用将导致Python执行该函数,并且只有在该调用结束后才继续向下。

在你的榜样,Python解释器将执行以下步骤:

  1. 定义func2
  2. Define func1
  3. 定义func
  4. 过程如果语句if __name__ == '__main__':
  5. 调用func函数(因为条件为真)。
  6. 调用func1函数(因为这就是func所做的)。
  7. 调用func2函数(因为这就是func1所做的)。
  8. 结束,因为在完成对func2的呼叫之后,它也完成呼叫func1,因此已完成调用func,这是代码中的最后一个声明。
0

对于你的问题(在Python编码风格)的第二部分,我会看看PEP 8,提供由Guido van Rossum的(在BFDL自己!),并写了一个风格指南提供了编写Pythonic代码的基础知识。