# Python Course

Previous Chapter: Namespaces
Next Chapter: Memoization with Decorators

## Global and Local Variables

The way Python uses global and local variables is maverick. While in many or most other programming languages variables are treated as global if not otherwise declared, Python deals with variables the other way around. They are local, if not otherwise declared. The driving reason behind this approach is that global variables are generally bad practice and should be avoided. In most cases where you are tempted to use a global variable, it is better to utilize a parameter for getting a value into a function or return value to get it out. Like in many other program structures, Python also imposes good programming habit by design.
So when you define variables inside a function definition, they are local to this function by default. This means that anything you will do to such a variable in the body of the function will have no effect on other variables outside of the function, even if the have the same name. This means that the function body is the scope of such a variable, i.e. the enclosing context where this name with its values is associated.
All variables have the scope of the block, where they are declared and defined in. They can only be used after the point of their declaration.
Just to make things clear: Variables don't have to be and can't be declared in the way they are declared in programming languages like Java or C. Variables in Python are implicitly declared by defining them, i.e. the first time you assign a value to a variable, this variable is declared and has automatically the the data type of the object which has to be assigned to it. If you have problems understanding this, please consult our chapter about data types and variables, see links on the left side.

### Global and local Variables in Functions

In the following example, we want to demonstrate, how global values can be used inside the body of a function:

    def f():
        print(s)
    s = "I love Paris in the summer!"
    f()

The variable s is defined as the string "I love Paris in the summer!", before calling the function f(). The body of f() consists solely of the "print(s)" statement. As there is no local variable s, i.e. no assignment to s, the value from the global variable s will be used. So the output will be the string "I love Paris in the summer!". The question is, what will happen, if we change the value of s inside of the function f()? Will it affect the global variable as well? We test this in the following piece of code:

    def f():
        s = "I love London!"
        print(s)

    s = "I love Paris!"
    f()
    print(s)

The output looks like this:

    I love London!
    I love Paris!

What if we combine the first example with the second one, i.e. first access s with a print() function, hoping to get the global value, and then assigning a new value to it? Assigning a value to it, would mean creating a local variable s. So, we would have s both as a global and a local variable in the same scope, i.e. the body of the function. Python doesn't allow this ambiguity. So, it will throw an error, as we can see in the following example:

    >>> def f():
    ...   print(s)
    ...   s = "I love London!"
    ...   print(s)
    ...
    >>> s = "I love Paris!"
    >>> f()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in f
    UnboundLocalError: local variable 's' referenced before assignment
    >>>

A variable can't be both local and global inside of a function. So Python decides that we want a local variable due to the assignment to s inside of f(), so the first print statement before the definition of s throws the error message above. Any variable which is changed or created inside of a function is local, if it hasn't been declared as a global variable. To tell Python, that we want to use the global variable, we have to explicitly state this by using the keyword "global", as can be seen in the following example:

    def f():
        global s
        print(s)
        s = "Only in spring, but London is great as well!"
        print(s)

    s = "I am looking for a course in Paris!"
    f()
    print(s)

We have solved our problem. There is no ambiguity left. The output of this small script looks like this:

    I am looking for a course in Paris!
    Only in spring, but London is great as well!
    Only in spring, but London is great as well!

Local variables of functions can't be accessed from outside, when the function call has finished:

    def f():
        s = "I am globally not known"
        print(s)

    f()
    print(s)

Starting this script gives us the following output with an error message:

    monty@python:~$ python3 ex.py
    I am globally not known
    Traceback (most recent call last):
      File "ex.py", line 6, in <module>
        print(s)
    NameError: name 's' is not defined
    monty@python:~$

The following example shows a wild combination of local and global variables and function parameters:

    def foo(x, y):
        global a
        a = 42
        x,y = y,x
        b = 33
        b = 17
        c = 100
        print(a,b,x,y)

    a,b,x,y = 1,15,3,4
    foo(17,4)
    print(a,b,x,y)

The output looks like this:

    42 17 4 17
    42 15 3 4

Previous Chapter: Namespaces
Next Chapter: Memoization with Decorators