dadiletta
dadiletta

Reputation: 299

Mysterious Python global vs function scope issue

def take_damage():
  health -= 20  # UNDERSTANDABLE ERROR

def check_health():
  if (health <= 0):   # WHY NO ERROR HERE, TOO?
    print("You have died!")
    quit()
  else:
    print("Your health is "+ str(health)) # HOW DOES IT WORK HERE?
     
  
health = 100
take_damage()
check_health()

Now, if I wanted to use this code, I'd start each method with global health to reach beyond the function's local scope. However, I'm at a loss as to explain why check_health doesn't throw an error in much the same way that take_damage will. Could anyone provide an explanation, please?

Upvotes: 0

Views: 42

Answers (2)

Dave Mcsavvy
Dave Mcsavvy

Reputation: 520

When you call health -= 20 inside a function, python searches inside the function for the health variable. What you did is like doing

health = health - 20

but since health has not been previously defined in that namespace, an error is thrown.

Upvotes: 1

chepner
chepner

Reputation: 531135

In take_damage, the assignment defines health as a local variable.

In check_health, the lack of an assignment makes health a free variable. The value of a free variable is taken from the closest enclosing scope where the variable is defined. Because health is defined in the global scope before check_health is called, no NameError results.

As an aside, the purpose of global health inside a function would be to change health from a free variable to a global variable, so that both assignments and lookups would occur in the global scope.

Upvotes: 3

Related Questions