[Tutor] global list
Steven D'Aprano
steve at pearwood.info
Thu Apr 24 03:00:01 CEST 2014
On Wed, Apr 23, 2014 at 04:46:49PM -0700, Denis Heidtmann wrote:
> In a coursera python course video the following code was presented:
>
> a = [4,5,6]
>
> def mutate_part(x):
> a[1] = x
>
> mutate_part(200)
>
> The presenter said something like "a is a global variable, so a becomes
>
> [4,200,6] after running mutate_part(200)."
>
> Indeed it does, but why does this work without specifying a as global
> within mutate()?
> My thinking was that an "undefined" error should have been raised.
You only need to define variables as global if you assign to them:
def function(x):
global a
a = [1, 2, 3, x] # assignment to variable "a"
The preferred name for this sort of assignment is "name binding", where
you bind a value (in this case, the list [1, 2, 3, x]) to the name "a".
You only need to declare variables as global when you perform a name
binding on that variable.
Merely retrieving the existing value of a variable doesn't count as
a binding, and doesn't need to be declared:
# This is okay
def function():
n = len(a)
# This is not needed
def function(x):
global len # Yes, built-in functions are variables too!
global a
n = len(a)
and that would be too painful for words.[1]
Now, let's go back to your function:
def mutate_part(x):
a[1] = x
It looks like a name binding (an assignment) to a, but look more
closely: you're not actually binding to the name "a", you are binding to
the item *inside* a. After calling "a[1] = x", a remains bound to the
same list as before, it is just that the list has been modified
in-place. So this does not count as a name binding operation, and no
global declaration is needed.
The same applies to mutating dicts in place, or setting attributes.
These are all examples of in-place modifications:
some_dict.clear()
some_list.sort()
obj.attribute = 23
some_dict[key] = value
del some_list[0]
Only actual assignments to the bare name, including deleting the name,
need a global declaration:
some_dict = {}
some_list = [1, 2, 3]
obj = something()
del some_list
[1] For advanced users: built-ins aren't technically "global", they
actually live in a separate namespace called "builtins" or "__builtin__"
depending on the version of Python you use. But the principle is the
same.
--
Steven
More information about the Tutor
mailing list