Python Scope & Namespace

Namespace — the concept of naming (variables, functions, etc.) and where you name them, which affects their scope.

Local scope

def drink_potion():
    potion_strength = 2   # var has local scope
    print(potion_strength)
 
drink_potion()
# console gives 2

Global scope

player_health = 10   # var has global scope
 
def drink_potion():
    potion_strength = 2
    print(player_health)
 
drink_potion()
# console gives 10
# this local/global thing works because you're not altering it

Python does not have block scope (e.g., if)

game_level = 3
enemies = ["skeleton", "zombie", "alien"]
 
if game_level < 5:
    new_enemy = enemies[0]   # var does NOT have local scope even though indented
 
print(new_enemy)
# console gives skeleton

Modifying global variables (avoid this!)

# Bad method
enemies = 1
 
def increase_enemies():
    global enemies
    enemies += 1   # trying to change global scope
    print(enemies)
 
# Good method
enemies = 1
 
def increase_enemies():
    return enemies + 1
 
increase_enemies()
print(increase_enemies())

Python constants

PI = 3.14159
# Use uppercase to define variables that you never plan to change ever again

Order matters — when you call it

num = 10
 
def square(n):
    global num
    num = 5
    return n**2
 
print(square(3) * num)
# Here the function happened before using num.
# num is now 5
 
print(num * square(3))
# Here num is called before square(n)
# Hence the num used is 10

Nesting structures

List inside dict

dict = {
    "name": ["a", "b", "c"]
}

Dict inside dict

dict = {
    "name": {"city": "singapore"}
}

Dict inside list

list = [
    {"key":  "value"},
    {"key2": "value2"},
]

See next