简体   繁体   English

Python 中的执行顺序和编码风格

[英]Order of execution and style of coding in Python

I am new to Python so please don't flame me if the question is too basic :)我是 Python 新手,所以如果问题太基本,请不要喷我 :)

I have read that Python is executed from top - to - bottom.我读过 Python 是从上到下执行的。

If this is the case, why do programs go like this:如果是这样,为什么程序会这样:

def func2(): 
    pass

def func1():
    func2()

def func():
    func1()

if __name__ == '__main__':
    func()

So from what I have seen, the main function goes at last and the other functions are stacked on top of it.所以从我所看到的,主函数最后运行,其他函数堆叠在它上面。

Am I wrong in saying this?我这样说有错吗? If no, why isn't the main function or the function definitions written from top to bottom?如果不是,为什么主函数或函数定义不是从上到下写的?

EDIT: I am asking why I can't do this:编辑:我在问为什么我不能这样做:

if __name__ == '__main__':
    func()

def func1():
    func2()

Isn't this the natural order?这不是自然规律吗? You keep on adding stuff at the bottom, since it is executed from top to bottom.你继续在底部添加东西,因为它是从上到下执行的。

The def s are just creating the functions. def只是创建函数。 No code is executed, other than to parse the syntax and tie functions to those names.除了解析语法并将函数绑定到这些名称之外,不执行任何代码。

The if is the first place code is actually executed. if是第一个实际执行的代码。 If you put it first, and call a function before it is defined, the result is a NameError.如果你把它放在第一位,并在它被定义之前调用一个函数,结果是一个 NameError。 Therefore, you need to put it after the functions are defined.因此,你需要把它放在函数定义之后。

Note that this is unlike PHP or JavaScript, where functions are 'hoisted' - any function definitions are processed and parsed before everything else.请注意,这与 PHP 或 JavaScript 不同,其中函数是“提升”的——任何函数定义都在其他任何事情之前被处理和解析。 In PHP and JavaScript, it's perfectly legal to do what you are saying and define functions in the source lower down than where they are called.在 PHP 和 JavaScript 中,按照您所说的去做并在源代码中定义函数低于调用它们的位置是完全合法的。 (One detail in JS is that functions defined like function(){} are hoisted, while functions defined like var func1=function(){}; are not. I don't know how it works with anonymous functions in PHP 5.3 yet). (JS 中的一个细节是,像function(){}定义的function(){}被提升,而像var func1=function(){};定义的var func1=function(){};不是。我不知道它如何与 PHP 5.3 中的匿名函数一起工作) .

See, in this, cat() will print correctly, and yip() gives you a NameError because the parser hasn't gotten to the definition of yip() at the time you call it.看,在这里, cat()将正确打印,而yip()会给你一个 NameError 因为解析器在你调用它yip()没有得到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文件“cat.py”,第 5 行,在
yip()叶()
NameError: name 'yip' is not defined NameError: 名称 'yip' 未定义

Python is executed from top to bottom, but executing a "def" block doesn't immediately execute the contained code. Python 从上到下执行,但执行“def”块不会立即执行包含的代码。 Instead it creates a function object with the given name in the current scope.相反,它在当前范围内创建一个具有给定名称的函数对象。 Consider a Python file much like your example:考虑一个与您的示例非常相似的 Python 文件:

def func2():
    print "func2"

def func1():
    func2()

def func():
    func1()

if __name__ == '__main__':
    func()

What happens when this script is executed is as follows:执行此脚本时发生的情况如下:

Firstly, a function object is created and bound to the name "func2" in the global scope.首先,在全局范围内创建一个函数对象并绑定到名称“func2”。 Then a function object is created and bound to the name "func1" in the global scope.然后创建一个函数对象并绑定到全局作用域中的名称“func1”。 Then one called "func".然后一个叫做“func”。 Then the "if" statement is executed, the condition is true and the "func()" statement is executed.然后执行“if”语句,条件为真,执行“func()”语句。 At this point "func" is a function object found in the global scope, so it is invoked and its code runs.此时“func”是在全局作用域中找到的一个函数对象,因此它被调用并运行其代码。 That code contains the "func1()" statement, which is resolved to a call to the "func1" function, and so on.该代码包含“func1()”语句,该语句被解析为对“func1”函数的调用,依此类推。

If you put the "if" statement at the top then when it executes there would not yet be anything defined with the name "func", so you would get an error.如果您将“if”语句放在顶部,那么当它执行时,还没有使用名称“func”定义任何内容,因此您会收到错误消息。 The important thing to recognise is that the "def" statement is itself a statement that is executed.要认识到的重要一点是“def”语句本身就是一个被执行的语句。 It is not like in some other languages where definitions are a separate sort of declaration with no order of execution.它不像在其他一些语言中定义是一种没有执行顺序的单独声明。

Also note that so long as the " if __name__ ..." bit is at the end of the file, it doesn't really matter what order the other declarations are in, since by the time any of them are called all of the "def"s will have already been executed.还要注意,只要“ if __name__ ...”位在文件的末尾,其他声明的顺序并不重要,因为当它们中的任何一个被称为所有“ def"s 将已经被执行。

Python does, in general, process commands from top to bottom.一般来说,Python 确实从上到下处理命令。 However, a function call will cause Python to execute that function, and continue downward only after that call has ended.但是,函数调用将导致 Python 执行该函数,并且只有在该调用结束后才继续向下。

In your example, the Python interpreter executes the following steps:在您的示例中,Python 解释器执行以下步骤:

  1. Define func2 .定义func2
  2. Define func1 .定义func1
  3. Define func .定义func
  4. Process if statement if __name__ == '__main__': .处理 if 语句if __name__ == '__main__':
  5. Call the func function (since the condition is true).调用func函数(因为条件为真)。
  6. Call the func1 function (because that's what func does).调用func1函数(因为func这样做的)。
  7. Call the func2 function (because that's what func1 does).调用func2函数(因为这就是func1所做的)。
  8. End, because after finishing the call to func2 it has also finished calling func1 and therefore has finished calling func , which was the final statement in the code.结束,因为在完成对func2的调用后,它也完成了对func1调用,因此也完成了对func调用,这是代码中的最后一条语句。

def statements simply define a function - they don't actually run it until the function is invoked. def语句只是定义了一个函数 - 在调用该函数之前,它们实际上不会运行它。 Hence why they generally come before whatever code uses them - they set the function up to be used in the future.因此,为什么它们通常在使用它们的任何代码之前出现 - 他们将函数设置为将来使用。

There's no hard requirement that def statements come before anything else, it's just fairly common to put the __main__ code at the bottom (among other things, it makes it clear what's in that section and what isn't, since anything below the if is part of that section).没有硬性要求def语句出现在其他任何东西之前,将__main__代码放在底部是相当常见的(除其他外,它清楚地说明了该部分中的内容和不包含的内容,因为if下面的任何内容都是一部分该部分)。 It also makes sure whatever you want to call from the section has already been def 'd.这也可以确保无论你怎么称呼从部分已是def “d。

The if __name__ == "__main__" part goes at the end, because presumably whatever your main function does will need all the other definitions in the script. if __name__ == "__main__"部分放在最后,因为大概你的 main 函数做什么都需要脚本中的所有其他定义。 If there were any other function definitions below the main block, then it would not be possible for them to be used in there, since they haven't been seen by the interpreter at that point.如果在主块下面有任何其他函数定义,那么它们就不可能在那里使用,因为在那时解释器还没有看到它们。

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

It's true that the convention is to put the "main" function just above the " if __name__ == '__main__' " statement at the end of the file.确实,约定是将“main”函数放在文件末尾的“ if __name__ == '__main__' ”语句之上。 I think that this is because we usually want functions to be near to their calling sites.我认为这是因为我们通常希望函数靠近它们的调用站点。

As for the called function coming above the calling function, I think that this is just a result of refactoring.至于在调用函数之上的被调用函数,我认为这只是重构的结果。 At least in my case, I tend to write a function, and then take out bits of code to put into sub-functions, which I put on top so that I can see better.至少在我的情况下,我倾向于编写一个函数,然后取出一些代码放入子函数中,我把它们放在上面以便我能看得更清楚。

This is just a primitive form of code organization.这只是代码组织的一种原始形式。 If there's a stronger cohesive unit, I'd be tempted to pull those functions into their own module.如果有一个更强大的内聚单元,我很想将这些功能拉入它们自己的模块中。

It's also worth noting that you can have function calls written occur "before they're defined", as long as they aren't executed.还值得注意的是,您可以在“定义之前”编写函数调用,只要它们不被执行。 Mentioning this here as it's a common new-to-python error.在这里提到这一点,因为它是一个常见的 Python 新手错误。 None of the other examples demonstrate this "it's ok, in one way" behavior.其他示例都没有证明这种“以一种方式还可以”的行为。 (though not really recommended) (虽然不是很推荐)

def hi():
  pie()

#hi() cannot be called here, doesn't work because hi depends on pie

def pie():
  print('hi pie')

hi() # it's ok to call here!

You can even go a little further (slightly silly example, but I believe it clarifies the example)你甚至可以更进一步(有点愚蠢的例子,但我相信它澄清了这个例子)

runIt = False
def hi():
  if runIt:
    pie()

hi() #now ok, as the code won't call pie.
runIt = True
#hi() #wouldn't be ok as now the code will call pie.

def pie():
  print('hi pie')

hi() # ok here too!

There is two points that you need to know :有两点你需要知道:

  1. The main condition is to block the prevent code from being run when the module is imported. main条件是在导入模块时阻止阻止代码运行。 In our case, the condition is true because our file is not imported.在我们的例子中,条件为真,因为我们的文件没有被导入。
  2. The code is working as follows :代码工作如下:
    • Define func2定义func2
    • Define func1定义func1
    • Define func定义func
    • Process if statement if __name__ == '__main__' : (which in our case is True )处理 if 语句if __name__ == '__main__' :(在我们的例子中是True
    • Call the func function调用func函数
    • Call the func1调用func1
    • Call the func2 function调用func2函数
    • return the result(print the message func2 )返回结果(打印消息func2
    • End结尾

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM