1

I just come across a confusion ,let's consider the below 2 codes

first code:

def out():        #func1
    print i
i=5

Output:5

Second:

def inc():        #func2
        i=i+1
        print i
i=5

When execiting the above programs ,func1 doesn't give any error but func2 gives an error...

error: var i referenced before assignment

I am confused that i is a local variable or global.If it is local variable then how func1 is accessing it and if it's global then why func2 is unable to access it?

user3223301
  • 201
  • 4
  • 11
  • possible duplicate of [Python variable scope question](http://stackoverflow.com/questions/370357/python-variable-scope-question) – hivert Mar 04 '14 at 09:31
  • See **[Why is global needed only on assignment and not on reads?](http://stackoverflow.com/questions/10360229/python-why-is-global-needed-only-on-assignment-and-not-on-reads)** – sjy Mar 04 '14 at 09:35

2 Answers2

4

That depends, when you assign a variable inside a function using the = operator, it will shadow any other outer scopes declaration of the variable and use local instead, unless it's declared global inside the function.

For example, your second try will work as you expected if you would do it like this:

def inc():        #func2
    global i
    i=i+1
    print i
i=5

On the other side, if no assignment is performed inside a function, it will use outer scopes declaration, as you saw in your first try.

Also, if you use global i but no i is defined in outer scopes the function will raise a not defined exception as well.

Paulo Bu
  • 29,294
  • 6
  • 74
  • 73
  • Yes, it does not override other outer scopes declarations. Read about namespaces (I assume you know what happens but you failed to express yourself correctly) – Ionut Hulub Mar 04 '14 at 09:35
  • @IonutHulub You're right _overrides_ is not the word because that would mean that it would affect the outer scope declaration. I assume _shade_ is a better word for that? I don't know exactly what word to use LOL – Paulo Bu Mar 04 '14 at 09:37
  • 1
    I don't know exactly the word either... I guess shade works. However overrides is definetely wrong. – Ionut Hulub Mar 04 '14 at 09:38
  • The word you're looking for is [*shadow*](http://dictionary.reference.com/browse/shadow?s=t) (its verb sense). – user4815162342 Mar 04 '14 at 11:18
  • @user4815162342 there you go! Thank you very much, _shade_ was close enough I guess. Sorry about that English is not my mother language :) Fixing it! – Paulo Bu Mar 04 '14 at 11:20
1

You need to declare i as global in func2 to be able to modify it's value.

def func_2():
    global i
    i=i+1
    print i

Without the global statement, you would be incrementing a variable local to func_2 without actually first giving it a value. And that's where your error comes from.

You can print the contents of global variables without declaring them global. You can also access mutable containers like lists and dictionaries without the global statment but strings, integers, floats and so forth cannot be modified without first making them global.

Examples:

>>> i = [1, 2, 3]
>>> def func_3():
...    i.append(4)
...    print i
>>> func_3()
[1, 2, 3, 4]

>>> i = "foo"
>>> def func_4()
...    i = "bar"
...    print i
>>> func_4()
"bar"
>>> print i
"foo"
msvalkon
  • 11,887
  • 2
  • 42
  • 38
  • This is the best answer yet but you should also explain why. The interpreter looks in the outer scope of the function only if you intend to read the value of a variable. If you intend to write to it the interpreter won't look in the outer scope unless you add `global i` at the beginning. – Ionut Hulub Mar 04 '14 at 09:34