在 Python atexit 函数中,函数内设置的字符串不可见?

In a Python atexit function, strings set inside a function aren't visible?

我 运行 昨天在 Python 2.7.10 下 运行 遇到了一个不寻常的 atexit 范围问题(尽管问题也在 Python 3 中)。函数内设置的全局字符串对我的 atexit 函数似乎不可见,而全局列表很好。我已将问题案例简化为:

import atexit

myString1 = None
myString2 = None
myArray1 = []
myArray2 = []

def setString1(newString):
    myString1 = newString

def setArray1(newString):
    myArray1.append(newString)

def testFinishUp():
    print("myString1 = " + str(myString1))
    print("myString2 = " + str(myString2))
    print("myArray1  = " + str(myArray1))
    print("myArray2  = " + str(myArray2))

setString1("Hello")
myString2 = "World"
setArray1("HELLO")
myArray2.append("WORLD")
atexit.register(testFinishUp)

输出的是:

myString1 = None
myString2 = World
myArray1  = ['HELLO']
myArray2  = ['WORLD']

现在,我确信 myString1 的行为方式与其他所有行为不同的原因有一个与范围相关的逻辑原因,但我个人看不出它是什么。 :-(

谁能解释一下这是怎么回事?谢谢!

如果你想操作一个全局不可变变量,你需要在该函数中添加 global var

在你的例子中,你正在向数组中添加一些东西,所以数组引用不会被操纵,因此你不需要指定,这是一个全局变量,但字符串本身会被操纵。

添加:global myString1 以上:myString1 = newString

应该可以解决问题。

如需进一步阅读,请参阅 python doc

这没什么奇怪的。你的问题是这条语句:

A global string set inside a function seems not to be visible to my atexit function, whereas global lists are fine.

为假。您没有在函数内部设置全局字符串。相反,您在函数范围内创建它的本地版本,以覆盖全局版本。如果你真的想改变全局值,你应该这样做:

def setString1(newString):
    global myString1
    myString1 = newString

它适用于您的列表的原因是您可以就地修改它们(通过 append)而不是创建副本。如果你愿意做

def setArray1(newString):
    myArray1 = myArray1 + [newString]

您会看到与字符串大小写完全相同的行为。

不过要提醒一句:从函数修改全局状态通常被认为是不好的风格,因为它混淆了设置值的位置。通常,最好在全局范围内修改值,例如通过分配给函数调用的结果。