Global dictionaries don't need keyword global to modify them?

dictionary, global, global-variables, python, scope

Solution

The reason is that the line

stringvar = "bar"

is ambiguous, it could be referring to a global variable, or it could be creating a new local variable called `stringvar`. In this case, Python defaults to assuming it is a local variable unless the `global` keyword has already been used.

However, the line

dictvar['key1'] += 1

Is entirely unambiguous. It can be referring only to the global variable `dictvar`, since `dictvar` must already exist for the statement not to throw an error.

This is not specific to dictionaries- the same is true for lists:

listvar = ["hello", "world"]

def listfoo():
    listvar[0] = "goodbye"

or other kinds of objects:

class MyClass:
    foo = 1
myclassvar = MyClass()

def myclassfoo():
    myclassvar.foo = 2

It's true whenever a mutating operation is used rather than a rebinding one.

Problem

I wonder why I can change global dictionary without `global` keyword? Why it's mandatory for other types? Is there any logic behind this? E.g. code: ``` #!/usr/bin/env python3 stringvar = "mod" dictvar = {'key1': 1, 'key2': 2} def foo(): dictvar['key1'] += 1 def bar(): stringvar = "bar" print(stringvar) print(dictvar) foo() print(dictvar) print(stringvar) bar() print(stringvar) ``` Gives following results: ``` me@pc:~/$ ./globalDict.py {'key2': 2, 'key1': 1} {'key2': 2, 'key1': 2} # Dictionary value has been changed mod bar mod ``` where I would expect: ``` me@pc:~/$ ./globalDict.py {'key2': 2, 'key1': 1} {'key2': 2, 'key1': 1} # I didn't use global, so dictionary remains the same mod bar mod ```

Original source

Related problems