Below, we demonstrate way to pass data to and from functions in different ways, and with different effects.
def adjust_grade():
global grade
grade = grade - 5
print("New grade inside the function:", grade)
if __name__ == "__main__":
grade = 95
adjust_grade()
print("New grade outside the function:", grade)
Since the grade inside the function is global
, the global variable grade gets modified when the function runs.
def adjust_grade2(grade):
grade = grade - 5
print("New grade inside the function:", grade)
if __name__ == "__main__":
grade = 95
adjust_grade2(grade)
print("New grade outside the function:", grade)
Here, grade
is a parameter of the function adjust_grade2()
(as well as a global variable.) When grade is modified inside the function, it's the local variable that gets modified. The global variable remains the same.
def adjust_grade3(g):
g = g - 5
print("New grade inside the function:", g)
if __name__ == "__main__":
grade = 95
adjust_grade3(grade)
print("New grade outside the function:", grade)
This is the exact same thing as before: the parameter g
just got renamed. Just like in math, f(x)=x
and f(y)=y
represent the same function.
def adjust_grade4(g):
global grade
grade = g - 5
if __name__ == "__main__":
grade = 95
adjust_grade4(grade)
print("New grade outside the function:", grade)
This works basically like adjust_grade()
: the global variable grade
gets modified.
def get_adjusted_grade(grade):
return grade - 5
if __name__ == "__main__":
grade = 95
get_adjusted_grade(grade)
print("New grade outside the function:", grade)
This outputs nothing: that's because while get_adjusted_grade(grade)
has the right value, the value doesn't get stored anywhere. Here' is how we can fix this:
def get_adjusted_grade(grade):
return grade - 5
if __name__ == "__main__":
grade = 95
grade = get_adjusted_grade(grade)
print("New grade outside the function:", grade)
We assign get_adjusted_grade(grade)
to grade
, and now everything works.
Now, here are two variants that produce errors:
def adjust_grade_error():
grade = grade - 5
print("New grade inside the func:", grade)
if __name__ == "__main__":
grade = 95
grade = adjust_grade_error()
The problem here is that in adjust_grade_error()
, we first evaluate grade - 5
, in order to store it back in grade
. That implies that the grade
we mean must be global -- we don't have a local grade
yet. On the other hand, the fact that we assign to grade
without going global grade
means grade
must be local. That is the assumption that Python goes with, resulting in the error message above. The error message says that Python assumed grade
was local, but there wasn't a local value of grade
that it could use to compute grade - 5
. It's the same problem as with
x = x + 2
Here is another function that would cause an error
def adjust_grade_error(grade):
global grade
grade = grade - 5
print("New grade inside the func:", grade)
We don't even need to call the function to get the error -- having grade
as a parameter implies it's local, but then we say that it's global
. Thsi causes an error.
We already did this (kind of), but let's write a function that explicitly uses global variables to pass data out:
def minus5(x):
global ret_val_minus5
ret_val_minus5 = x - 5
if __name__ == "__main__":
minus5(10)
print("Result:", ret_val_minus5)
The vast majority of the time, you want to pass the data as parameters to the function, and then return the data from the function:
def minus5(x):
return x - 5
if __name__ == "__main__":
print(minus5(15))
When do global variables make sense? One example is Lab 2 (unless you know about Python classes, which we won't be covering this semester.)
Recall that you need to keep track of the current value, and the previous value, and the memory value. The function add
would look something like
def add(current_value, previous_value, memory, to_add):
#...
#...
#...
return new_cur_value, new_prev_value, new_memory
That is cumbersome