我在功能块内的全局列表中使用.pop方法,但是在块外部正在更新全局列表。我以为局部变量不能修改全局变量。
这应该不起作用,但确实如此:
import random
PhraseBank = ['a','b','c','d']
def getPuzzle(secretphrase):
phraseIndex = random.randint(0,len(PhraseBank)-1)
secretphrase = PhraseBank.pop(phraseIndex)
return secretphrase #Returns and item indexed from the PhraseBank
while len(PhraseBank) != 0:
secretphrase = getPuzzle(PhraseBank) #works
print(secretphrase, PhraseBank)
OUTPUT是:
a ['b', 'c', 'd']
d ['b', 'c']
c ['b']
b []
为什么PhraseBank在我只在功能块中修改时会全局更新?
答案 0 :(得分:4)
列表是可变的。您正在更改PhraseBank引用的列表,但它仍然引用相同的列表。所以变量没有改变(仍然指同一个东西),但那个东西已经改变了。
答案 1 :(得分:3)
如果要为PhraseBank
分配值,除非您明确表示正在使用全局变量,否则不会更改该值。但是,Python中的每个var只是对象的命名引用。您读取var然后修改它引用的对象。是的,您无法更改引用本身,但您可以更改对象。
因此,您所面临的是Python最典型的功能之一。一切都是对象,所有变量都是引用。了解这一事实通常有助于理解许多可能看起来很奇怪的事情。一个很好的例子:
>>> li = [1]
>>> a = (li, li)
>>> a[0].append(1)
>>> a[1]
[1, 1]
>>> li
[1, 1]
>>> li.append(1)
>>> a
([1, 1, 1], [1, 1, 1])
如果上述代码的行为没有让您感到惊讶,那么您就能理解变量和对象是如何相关的。 :-)这里未更改的变量会被更改,但不是因为它们开始引用其他对象,而是因为它们引用的对象被修改。那些不可变的元组也是如此。对,他们是。元组一旦创建,总是指相同的对象。但是每个对象都可能会改变。
答案 2 :(得分:2)
您不能将分配给函数内的全局变量(除非您明确使用global
声明)。您可以很好地修改存储在全局变量中的对象。