Lin*_*Lin 15 python initialization
我是来自C++背景的Python新手.虽然我知道尝试使用我的旧C++知识找到匹配的概念并不是Pythonic,但我认为这个问题仍然是一个普遍的问题:
在C++下,有一个众所周知的问题叫做全局/静态变量初始化命令惨败,因为C++无法决定哪个全局/静态变量首先在编译单元中初始化,因此全局/静态变量取决于另一个编译单元单元可能早于其依赖对应物初始化,并且当依赖开始使用依赖对象提供的服务时,我们将有未定义的行为.在这里,我不想深入了解C++如何解决这个问题.:)
在Python世界中,我确实看到全局变量的使用,甚至跨越不同的.py文件,我看到的一个典型用例是:在一个.py文件中初始化一个全局对象,在其他.py文件中,代码无所畏惧开始使用全局对象,假设它必须已经在其他地方初始化,由于我上面指出的问题,在C++下我自己肯定不会接受.
我不确定上述用例是否是Python(Pythonic)中的常见做法,以及Python如何解决这种全局变量初始化顺序问题?
非常感谢你!
林
Ign*_*ams 12
Python导入从头到尾执行新的Python模块.后续导入仅导致现有引用的副本sys.modules,即使由于循环导入仍在导入模块的中间.在循环导入存在之前已初始化的模块属性("全局变量"实际上在模块范围内).
main.py:
import a
Run Code Online (Sandbox Code Playgroud)
a.py:
var1 = 'foo'
import b
var2 = 'bar'
Run Code Online (Sandbox Code Playgroud)
b.py:
import a
print a.var1 # works
print a.var2 # fails
Run Code Online (Sandbox Code Playgroud)
Dav*_*d Z 11
在C++下,有一个众所周知的问题叫做全局/静态变量初始化顺序惨败,因为C++无法决定哪个全局/静态变量首先在编译单元中初始化,
我认为该声明强调了Python和C++之间的关键区别:在Python中,没有不同的编译单元.我的意思是,在C++中(如你所知),两个不同的源文件可能完全相互独立编译,因此如果你比较文件A中的一行和文件B中的一行,就没有什么好说的了.你将在计划中获得第一名.这有点像多线程的情况:你不能说线程1中的特定语句是在线程2中的特定语句之前还是之后执行.你可以说C++程序是并行编译的.
相反,在Python中,执行从一个文件的顶部开始,并通过文件中的每个语句以明确定义的顺序进行,并在导入它们的位置分支到其他文件.实际上,您几乎可以将该import指令视为一个#include,并且以这种方式,您可以识别程序中所有源文件中所有代码行的执行顺序.(嗯,它比这复杂一点,因为模块只在第一次导入时才真正执行,并且由于其他原因.)如果C++程序是并行编译的,那么Python程序将被串行解释.
您的问题也涉及Python中模块的深层含义.Python模块 - 它是单个.py文件中的所有内容 - 是一个实际的对象.在单个源文件中在"全局"范围内声明的所有内容实际上都是该模块对象的属性.Python中没有真正的全局范围.(Python程序员经常说"全局",实际上global语言中有一个关键字,但它总是指的是当前模块的顶层.)我可以看到这是一个有点奇怪的概念来习惯来来自C++背景.我花了一些时间来习惯,来自Java,在这方面,Java比C++更类似于Python.(Java中也没有全局范围)
我会提到在Python中使用变量是完全正常的,而不知道它是否已经初始化/定义.嗯,也许不正常,但在适当的情况下至少可以接受.在Python中,尝试使用未定义的变量会引发一个NameError; 你不会像在C或C++中那样获得任意行为,因此你可以轻松处理这种情况.你可能会看到这种模式:
try:
duck.quack()
except NameError:
pass
Run Code Online (Sandbox Code Playgroud)
如果duck不存在则什么都不做.实际上,你更常见的是
try:
duck.quack()
except AttributeError:
pass
Run Code Online (Sandbox Code Playgroud)
如果duck没有名为的方法,它什么都不做quack.(AttributeError当你试图访问一个对象的属性时,你得到的那种错误,但是该对象没有该名称的任何属性.)这是Python中的类型检查所传递的:我们认为如果我们只需要鸭子要做的就是嘎嘎叫,我们可以问它嘎嘎叫,如果确实如此,我们不在乎它是不是真的 是鸭子.(它被称为鸭子打字;-)