035-002. creating method inside of method, global keyword, nonlocal keyword
@
def print_hello():
hello = 'Hello, world!'
def print_message():
print(hello)
# I invoke print_message() inside of print_hello()
print_message()
print_hello()
# output:
# Hello, world!
@
# Inner method print_message() can use local variable of outter method print_hello()
def print_hello():
hello = 'Hello, world!'
def print_message():
# This one uses local variable of outter method print_hello()
print(hello)
# Local variable of outter method can be access any method which is created inside of outter method
@
# Let's try to change value of local variable of outter method inside of inner method
def calc():
# This is local variable of calc()
total = 0
def add(a, b):
# This code generates error
# because uninitialized local variable total is tried to use
total = total + a + b
add(10, 20)
add(30, 40)
print(total)
calc()
# output:
# Traceback (most recent call last):
# File "C:₩project₩function_local_error.py", line 10, in
# calc()
# File "C:₩project₩function_local_error.py", line 6, in calc
# add(10, 20)
# File "C:₩project₩function_local_error.py", line 4, in add
# total = total + a + b
# UnboundLocalError: local variable 'total' referenced before assignment
# Error message means "local variable total of add() is referenced before it's initialized"
# In Python, if you create variable inside of method, that variable must become local variable
# In this case, we didn't initialize variable total so we're not having any local variable
@
# If you want to change local variable of outter method,
# you can use "nonlocal" keyword on local variable (which you want to change) of outter method
def calc():
total = 0
def add(a, b):
# I declare I will use local variable total of outter method
nonlocal total
total = total + a + b
add(10, 20)
add(30, 40)
print(total)
calc()
# output:
# 100
@
# Meaning of "nonlocal" is it's not local variable of current inner method, but I use local variable as local variable of outter method
@
def calc(total):
def add(a, b):
# Since parameter is also local variable,
# you can apply nonlocal on parameter
nonlocal total
total = total + a + b
@
# When nonlocal finds local variable outside of current inner method,
# it finds from firstly nearest method
def A():
x = 10
y = 100
def B():
x = 20
def C():
nonlocal x
nonlocal y
x = x + 30
y = y + 300
print(x)
print(y)
C()
B()
A()
# output:
# 50
# 400
# When you use nonlocal on x inside of C method,
# it finds local variable x = 20 inside of B method
@
# No matter how deep steps methods have,
# if you use global keyword,
# methods find only global variable,
# with passing local variable inside of outter method
x = 1
def A():
x = 10
def B():
x = 20
def C():
global x
x = x + 30
print(x)
C()
B()
A()
# output:
# 31
@
# Even if Python provides global keyword,
# when you pass value and accept value,
# it's recommended to use parameter and return value
# Especially, when codes become complex, with global variable, you suffer difficulty of figuring out where variable is changed
# So, it's recommended not to use global variable