0

I am getting getting UnboundLocalError: local variable referenced before assignment error while trying to run this code. As per LEGB rule this should run fine.

def xyz():
    count = 1
    def xyz_inner():
        count += 1
        print count
    xyz_inner()
    print count
Vishnu Upadhyay
  • 5,043
  • 1
  • 13
  • 24
Nishant Srivastava
  • 449
  • 2
  • 7
  • 18

2 Answers2

1

The issue here is that the count in the inner function is bound by an (augmented) assignment statement, and is therefore regarded as local to xyz_inner(). Consequently, the first time the code attempts to execute count += 1 the (local) variable count has not previously been assigned, and so it is indeed an unbound local.

Use of nonlocal count inside xyz_inner() should rectify that problem by telling the interpreter you want to use xyz()'s count rather than creating a local.

holdenweb
  • 33,305
  • 7
  • 57
  • 77
  • Thanks for answer Now i modified my code to def xyz(): count = 1 def xyz_inner(): global count count += 1 print count xyz_inner() print count It is now giving NameError: global name 'count' is not defined however as per my understading since count has been defined in the enclosing function so this error should not come – Nishant Srivastava Dec 10 '14 at 09:10
  • Sadly, `global` means "in the module's namespace" not "in the lexically surrounding function's namespace", hence my suggestion to use `nonlocal`. Unfortunately I forgot that this is a Python 3 feature. Beware using globals for inter-component communication. It really messes up your software's cohesion. – holdenweb Dec 10 '14 at 11:18
0

see unbound local error

def xyz():
    count = 1
    def xyz_inner():
        count += 1
        print count, locals()
    xyz_inner()
    print count

print hasattr(globals, 'count')
print hasattr(xyz, 'count')

>>> 
False
False

Define variable in any mutable object like dict or list(uses same reference) and update it using augmented assignment.

it works:-

def xyz():
    count = {'value': 1}
    def xyz_inner():
        count['value'] += 1
        print count['value'],
    xyz_inner()
    print count

xyz()

see python closure for nonlocal in python2.7

Vishnu Upadhyay
  • 5,043
  • 1
  • 13
  • 24
  • Note that the statement `print hasattr(xyz, 'count')` tells you that the _function_ has no `count` attribute. This is not, however, the same thing as a function call's local namespace containing the name `count`. Function attributes are entirely separate from the call namespace. – holdenweb Dec 10 '14 at 11:21