擅长:python、mysql、java
<p>一个完整的答案需要对整个语言如何工作进行深入的解释,这已经被记录在案-<a href="https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces" rel="nofollow noreferrer">the official doc about scoping and namespaces</a>可能是这里最好的起点。在</p>
<p>长话短说,在Python中,一切都是一个对象,包括函数、类和模块,函数、模块和类没有明确的名称空间。在下面的代码中:</p>
<pre><code>FOO_FACTOR = 2
def foo(arg):
return bar(arg) * FOO_FACTOR
def bar(arg):
return arg + 3
</code></pre>
<p>{{{cd2>实际上是一个<cd2}的变量。如果不允许函数访问全局作用域中的名称,则必须显式地传递<code>bar</code>和{<cd3>},如果需要一个特殊的声明来访问全局变量,那么每次函数使用另一个函数、类或模块时,都必须编写大量的样板代码,这至少是不实际的。在</p>
<blockquote>
<p>allowing functions to use variables that have not been passed to them
obfuscates how that function interacts with other code pretty
severely.</p>
</blockquote>
<p>好吧,重新绑定(甚至只是改变)非本地名称确实会导致很多问题——wrt/readability(对代码进行推理的能力)、可测试性等等,但是wrt/concurrency和<a href="https://en.wikipedia.org/wiki/Reentrancy_(computing)" rel="nofollow noreferrer">reentrancy</a>,应该尽量避免。在</p>
<p>但从一个实际的视角来看,你很难避免至少有<em>只读的全局变量(符号常量、其他函数、类、模块等),有时,您还需要至少几个函数,它们确实会改变/重新绑定全局名称(例如,考虑应用程序设置)——这里的要点是,这些函数只应在应用程序启动时调用,以定义符号常量等</p>