Reputation: 299
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
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
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