Hello,

I need some help understanding the nonlocal variables and functions. Currently I'm reading "A byte of Python" to ease myself into the language, which so far seems to be fairly straightforward even if the syntax is a little strange coming from C++.

I have copied a small script from the book:

#!/usr/bin/python
# Filename: func_nonlocal.py
def func_outer():
	x = 2
	print('x is', x)
	
	def func_inner():
		nonlocal x
		x = 5

	func_inner()
	print('Changed local x to', x)
func_outer()

If I'm correct the code is read line by line by the interpreter and that When I call func_outer() it displays the data in the print(..) by going through the function one line after another. So what is the point of calling the func_inner() within the func_outer() since it is already defined inside the said function.

I ran the code after commenting the func_inner() and it ran fine without a problem.

Also is defining functions within functions advisable as it seems a rather strange concept, and can you call func_inner() without having to go through func_outer() first.
Say like

def func_outer():
	x = 2
	print('x is', x)
	
	def func_inner():
		nonlocal x
		x = 5

	func_inner()
	print('Changed local x to', x)
func_inner()                #Just call this

Thanks.
PS. What's the Python code tag? When I call \ I don't get the formating or syntax highlighting.[code=python\] I don't get the formating or syntax highlighting.

Proper Python code tags are ...
[code=python]
your Python code here

[/code]

A function within a function is very useful in functional programming and is commonly called a closure. When you define a function inside of another function, then any undefined local variable in the inner function will take the value of that variable from the outer function. Decorator functions typically use closures. I have commented your code to explain it a little better ...

#!/usr/bin/python
# Filename: func_nonlocal.py

def func_outer():
    x = 2
    print('x is', x)
    
    def func_inner():
        """
        func_inner() is local to func_outer()
        keyword nonlocal introduced in Python3
        will make x nonlocal to the next scope level
        in this case func_outer(), so x will now be 5 and not 2
        """
        nonlocal x
        x = 5

    func_inner()
    print('Changed local x to', x)

func_outer()
#func_inner()  # gives NameError: name 'func_inner' is not defined

"""
my result with line 'nonlocal x' -->
x is 2
Changed local x to 5

my result with line 'nonlocal x' commented out -->
x is 2
Changed local x to 2
"""

Here would be a simple example of functional programming using a function within a function ...

# combining functions in Python

def combine_two(f1, f2):
    """
    combine two functions f1 and f2
    having arguments *a
    """
    def inner(*a):
        return f1(f2(*a))
    return inner

def reverse(s):
    """reverse string s"""
    return s[::-1]

def uppercase(s):
    """convert string s to all upper case"""
    return s.upper()

# combine the two functions reverse() and uppercase()
rev_up = combine_two(reverse, uppercase)

print(rev_up('hello world!'))  # !DLROW OLLEH

Thank you for your reply.

If I understand correctly nonlocal will take the value defined in func_inner() and pass it the variable x in func_outer() .

Within the code for func_outer() after I leave the scope for func_inner() the function is called is there a purpose to this. As when I run the script after the commenting the line it still runs without a problem.
ie.

def func_outer():
	x = 2
	print('x is', x)
	
	def func_inner():
		nonlocal x
		x = 5

	func_inner()    #why do we call this?
	print('Changed local x to', x)

Thank you for your reply.

If I understand correctly nonlocal will take the value defined in func_inner() and pass it the variable x in func_outer() .

Within the code for func_outer() after I leave the scope for func_inner() the function is called is there a purpose to this. As when I run the script after the commenting the line it still runs without a problem.
ie.

def func_outer():
	x = 2
	print('x is', x)
	
	def func_inner():
		nonlocal x
		x = 5

	func_inner()    #why do we call this?
	print('Changed local x to', x)

If you don't call the inner function, then x=5 will not happen.

This question has already been answered. Start a new discussion instead.