<p>这是一个有趣的问题,因为字符串是不可变的。行<code>from globalEx1 import *</code>在<code>globalEx2</code>模块中创建了两个引用:<code>a</code>和<code>setvalue</code>。<code>globalEx2.a</code>最初是指与<code>globalEx1.a</code>相同的字符串对象,因为导入就是这样工作的。你知道吗</p>
<p>但是,一旦调用<code>setvalue</code>,它对<code>globalEx1</code>的全局变量进行操作,<code>globalEx1.a</code>引用的值就会被另一个string对象替换。由于字符串是不可变的,因此无法在适当的位置执行此操作。<code>globalEx2.a</code>的值仍然绑定到原始string对象,正如它应该绑定的那样。你知道吗</p>
<p>你这里有一些解决办法。最具python风格的是在<code>globalEx2</code>中修复导入:</p>
<pre><code>import globalEx1
print globalEx1.a
globalEx1.setvalue('200')
print globalEx1.a
</code></pre>
<p>另一种选择是为<code>a</code>使用可变容器,并访问:</p>
<pre><code>globals()['a']=['100']
def setvalue(val):
globals()['a'][0] = val
</code></pre>
<pre><code>from globalEx1 import *
print a[0]
setvalue('200')
print a[0]
</code></pre>
<p>第三个也是更为广泛的选择是使<code>globalEx2</code>的<code>setvalue</code>成为原始函数的副本,但将其<code>__globals__</code>属性设置为<code>globalEx2</code>的命名空间,而不是<code>globalEx1</code>:</p>
<pre><code>from functools import update_wrapper
from types import FunctionType
from globalEx1 import *
_setvalue = FunctionType(setvalue.__code__, globals(), name=setvalue.__name__,
argdefs=setvalue.__defaults__,
closure=setvalue.__closure__)
_setvalue = functools.update_wrapper(_setvalue, setvalue)
_setvalue.__kwdefaults__ = f.__kwdefaults__
setvalue = _setvalue
del _setvalue
print a
...
</code></pre>
<p>必须创建副本的原因是<code>__globals__</code>是只读属性,而且您不想弄乱<code>globalEx1</code>中的函数。见<a href="https://stackoverflow.com/a/13503277/2988730">https://stackoverflow.com/a/13503277/2988730</a>。你知道吗</p>