Variable scope (Python Newbie)

2019-05-23 07:49发布

问题:

I am using a .pop method on a Global list inside a function block, but the Global list is being updated outside the block. I thought that local variables can't modify Global variables.

This should not work, but it does:

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 is:

a ['b', 'c', 'd']
d ['b', 'c']
c ['b']
b []

Why is PhraseBank getting updated Globally when I am only modifying it inside a function block?

回答1:

You can't assign to a global variable inside a function (unless you explicitly use a global declaration). You can modify objects stored in global variables just fine.



回答2:

Lists are mutable. You are changing the list that PhraseBank refers to, but it's still referring to the same list. So the variable isn't changed (still refers to the same thing) but that thing has changed.



回答3:

If you were assigning a value to the PhraseBank, it would not be changed unless you say you are using the global variable explicitly. However, each var in Python is just a named reference to an object. You read the var and then modify the object it refers to. Yes, you can't change the reference itself, but you can change the object.

So, what you faced is one of the most typical features of Python. Everything is an object, all the variables are references. Understanding that fact often helps to understand many things that may seem strange. A good example:

>>> 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])

If nothing surprises you in the behavior of the code above, then you understand how are the variables and objects related. :-) Here the variables that are not touched are changed, but not because they start referring other objects, but because the objects they refer to are modified. So do the tuples that are immutable. Yes, they are. A tuple, once created, always refers to the same objects. But each of those object may be changed.



标签: python scope