0

I am trying to run following code in Python3.4, but I am getting error.

def checknumner():
    i = 0
    print("checknumber called...")
    def is_even():
        print("is_even called...")
        global i
        if i % 2 == 0:
            print("Even: ", i)
        else:
            print("Odd: ", i)
        i += 1
    return is_even

c = checknumner()
print(c())
print(c())
print(c())

I am not able to access variable "i" in sub function.

When I comment out "global i" statment

D:\Study\Python>python generator_without_generator.py checknumber called... is_even called... Traceback (most recent call last):   File "generator_without_generator.py", line 24, in <module>
    print(c())   File "generator_without_generator.py", line 16, in is_even
    if i % 2 == 0: UnboundLocalError: local variable 'i' referenced before assignment

When I add "global i" statment

D:\Study\Python>python generator_without_generator.py checknumber called... is_even called... Traceback (most recent call last):   File "generator_without_generator.py", line 24, in <module>
    print(c())   File "generator_without_generator.py", line 16, in is_even
    if i % 2 == 0: NameError: name 'i' is not defined

Can anyone please explain this?

Murtuza Z
  • 5,639
  • 1
  • 28
  • 52

1 Answers1

3

If you're using Python 3 (and it looks like you are), there's an amazing way to tackle this issue:

def function():
    i = 0
    def another_function():
        nonlocal i 
        # use 'i' here

Here, i isn't global as it would've been defined outside both functions otherwise. It also isn't local to another_function as it's defined outside it. So, it's non local.

More info about nonlocal:

Community
  • 1
  • 1
ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • Why is `nonlocal` at all necessary? Even in your example, this is just a closure, meaning the inner function _has_ access to the variables defined in the outer function. – the_constant Jan 21 '17 at 15:55
  • EDIT: It's the line `i += 1` that causes the reference error, but irregardless, `i` never gets increased even on repetitive calls with the given code, and `i` is still accessible via the closure's scope. – the_constant Jan 21 '17 at 16:05
  • 1
    @Vincenzzzochi the value of "I" increments and using nonlocal it works perfectly. – Murtuza Z Jan 21 '17 at 17:04