module scope and local scope

This is the place for queries that don't fit in any of the other categories.

module scope and local scope

Postby metulburr » Thu Apr 25, 2013 4:52 am

I have been meaning to ask this for a long time, but i keep forgetting. I just remember because i had this happen. This is all python3.x, specifically 3.2.3. But this confuses me sometimes when i make a typo, or i change the names of local vars, and local variables on global functions a lot.

So i minimize the code:
Code: Select all
def func(arg):
   print(arg)
   print(var)
   var = var + 'test'
   print(var)
   
var = 'i am var'
func('i am arg')

I get the expected, print(var) gets an UnboundLocalError
i am arg
Traceback (most recent call last):
File "forum4.py", line 9, in <module>
func('i am arg')
File "forum4.py", line 4, in func
print(var)
UnboundLocalError: local variable 'var' referenced before assignment


However if you take out the assignement to var and after:
Code: Select all
def func(arg):
   print(arg)
   print(var)
   #var = var + 'test'
   #print(var)
   
var = 'i am var'
func('i am arg')


it uses the the module var:
i am arg
i am var



Now normally i wouldnt care, as i would always assign var first before trying to use it, but when you typo, or typing a section of code ata a time, and forget the assignment of var, etc. This causes some unexpected results. For example, in the code i was using, module var was a tuple of 2 indexes, while the local var, was a list of multiple indexes. Then i changed the name of the local var, but forgot one name change. Now auto thinking is if i change the names of variables, i will get an error quickly, however in this example, it used the module var, so it took me a bit to hunt down this problem. Now obviously this would not be a problem if i didnt forget to ensure all variables were correctly changed, but I did forget one, which caused unexpected results.

And normally I use classes, so i dont have this problem, but if i am just testing something out, i normally use global functions and global vars passed to those functions first.

Now is that expected? I would of thought that the local variable var in the global function would always give an UnboundLocalError, unless it was declared global?
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1448
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: module scope and local scope

Postby Mekire » Thu Apr 25, 2013 5:15 am

Well I agree it is a tad odd. I wouldn't have expected this either. So it appears that even before you call the function the function knows what names are used within it. It knows you locally defined var so it doesn't try to find the global var. Then it fails because the print(var) looks for the local one and it isn't assigned yet. However if you comment out those lines it doesn't think there is a var local to the function and gets the global one without issue.

This to me points out how important it is to have a good naming convention (ie all capitol letters) when it comes to global constants.

-Mek

Edit: Just a clarification on the global statement. You can always use a global within a function without using the global statement. The only times you need that statement are; when you want a variable defined within the function to become part of the global scope; or if you want to modify the value of a global within a function. The first of which is usually a bad idea and the second of which is ALWAYS a bad idea.
User avatar
Mekire
 
Posts: 987
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: module scope and local scope

Postby stranac » Thu Apr 25, 2013 3:15 pm

Yes, that's expected.

As Mekire said, you're always able to access global names.
You only need the global statement when you want to assign to a global(you can modify them without using global).

The reason the first code raises UnboundLocalError is that assignment anywhere in a function makes the name local to that function.
So, even though there is a global named var, print() tries to access the local, which has not yet been assigned to.

There are a few explanations of how this works in the Programming FAQ of the docs.
Friendship is magic!

R.I.P. Tracy M. You will be missed.
User avatar
stranac
 
Posts: 1133
Joined: Thu Feb 07, 2013 3:42 pm

Re: module scope and local scope

Postby Mekire » Fri Apr 26, 2013 2:39 pm

Sorry, you are of course correct. What I meant by my statement was, you can't modify a global like this:
Code: Select all
def mod_glob():
    var += 1

var = 5
mod_glob()

Without adding the global keyword:
Code: Select all
def mod_glob():
    global var
    var += 1

var = 5
mod_glob()
print(var)

If the original global was a mutable to begin with then yeah you can modify it to your hearts content using inplace methods regardless.

-Mek
User avatar
Mekire
 
Posts: 987
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan


Return to General Coding Help

Who is online

Users browsing this forum: No registered users and 4 guests