<blockquote>
<p>Under C++, there is a well known problem called global/static variable initialization order fiasco, due to C++'s inability to decide which global/static variable would be initialized first across compilation units, </p>
</blockquote>
<P>我认为语句突出了Python和C++之间的关键区别:在Python中,没有不同的编译单元。我的意思是,在C++中(如你所知),两个不同的源文件可以完全独立地编译,因此,如果比较文件A中的一行和文件B中的一行,则没有什么可以告诉你哪一个将被放在程序中的第一位。这有点像多线程的情况:您无法确定线程1中的特定语句将在线程2中的特定语句之前还是之后执行。你可以说C++程序是并行编译的。在</p>
<p>相反,在Python中,执行从一个文件的顶部开始,按照定义良好的顺序通过文件中的每个语句执行,并在其他文件导入的位置分支到其他文件。实际上,您几乎可以将<code>import</code>指令看作<code>#include</code>,这样就可以确定程序中所有源文件中所有代码行的执行顺序。(嗯,这比它复杂一点,因为一个模块在第一次导入时才真正被执行,并且由于其他原因)如果C++程序并行编译,Python程序就被串行地解释。在</p>
<p>您的问题还涉及到Python中模块的深层含义。Python模块是一个实际的对象,它是单个<code>.py</code>文件中的所有内容。在单个源文件的“global”范围内声明的所有内容实际上都是该模块对象的属性。Python中没有真正的全局作用域。(Python程序员经常说“全局”,实际上,在语言中有一个^ {CD4}}关键字,但它总是指当前模块的顶层。)我可以看到,这是一个陌生的概念,习惯于从C++背景中来。我从java中得到一些习惯,在这方面,java比python更类似于C++。(Java中也没有全局范围)</p>
<p>我将提到,在Python中,使用一个变量而不知道它是否已被初始化/定义是完全正常的。嗯,也许不正常,但至少在适当的情况下是可以接受的。在Python中,试图使用未定义的变量会引发^ {< CD5> };您不能像C或C++那样任意地进行行为,因此您可以轻松地处理这种情况。您可能会看到这种模式:</p>
<pre><code>try:
duck.quack()
except NameError:
pass
</code></pre>
<p>如果<code>duck</code>不存在,则不执行任何操作。实际上,你通常会看到</p>
^{pr2}$
<p>如果<code>duck</code>没有一个名为<code>quack</code>的方法,则它不会执行任何操作。(<code>AttributeError</code>是当你试图访问一个对象的一个属性,但是这个对象没有这个名称的任何属性)这就是在Python中进行类型检查的原因:我们认为如果我们只需要鸭子呱呱叫,我们可以要求它呱呱叫,如果它叫了,我们就不在乎它是不是<em>真的</em>还是鸭子不是。(这叫做鸭子打字;-)</p>