472,143 Members | 1,314 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,143 software developers and data experts.

LEGB rule, totally confused ...

hello,

I've thought many times I finally understood the import / namespace rules,
but again I'm totally lost :-(

This is my library file

# Module lib_test.py

X = 1

def Init():
global X
X = 3
print 'Init', X

def Run ():
print X <=== UnboundLocalError: local variable
'X' referenced before assignment
X = X + 1
print ' Run', X

And this my main program in another file:

import lib_test
lib_test.Init()
print lib_test.X

lib_test.Run()
print lib_test.X

Why do I get the error ?
Printing isn't assigning anything or am I missing something.
Now if I remove "X = X + 1" I don't get an error ???
Is this a problem of the traceback procedure or the IDE,
or is Python not completely an interpreter, that reads line by line ???

Please explain this to me.

thanks,
Stef Mientki
Aug 14 '07 #1
6 1929
stef mientki wrote:
hello,

I've thought many times I finally understood the import / namespace rules,
but again I'm totally lost :-(

This is my library file

# Module lib_test.py

X = 1

def Init():
global X
X = 3
print 'Init', X

def Run ():
print X <=== UnboundLocalError: local variable
'X' referenced before assignment
X = X + 1
print ' Run', X

And this my main program in another file:

import lib_test
lib_test.Init()
print lib_test.X

lib_test.Run()
print lib_test.X

Why do I get the error ?
Printing isn't assigning anything or am I missing something.
Now if I remove "X = X + 1" I don't get an error ???
Is this a problem of the traceback procedure or the IDE,
or is Python not completely an interpreter, that reads line by line ???

Please explain this to me.
This are the scoping-rules of python. A variable name on the left side of an
name-binding/assignment operator (including augmented assignments, vulgo:
+= and brothers) will make the variable name a function-local.

So

x = 10
def foo():
print x
x = 100

makes x a local variable to foo, which of course can't be accessed in

print x

Diez
Aug 14 '07 #2
stef mientki a écrit :
hello,

I've thought many times I finally understood the import / namespace rules,
but again I'm totally lost :-(

This is my library file

# Module lib_test.py

X = 1

def Init():
global X
X = 3
print 'Init', X

def Run ():
print X <=== UnboundLocalError: local variable
'X' referenced before assignment
X = X + 1
print ' Run', X

And this my main program in another file:

import lib_test
lib_test.Init()
print lib_test.X

lib_test.Run()
print lib_test.X

Why do I get the error ?
Printing isn't assigning anything or am I missing something.
If you use a global to *modify* it, you MUST declare "global X", either
Python consider using a local.
So for your error: at compile time, in Run(), it see that it must use a
local X (because you set it) and generate ad-hoc bytecode, but when
running X is not defined locally, so the error.
Now if I remove "X = X + 1" I don't get an error ???
If you remove the "X =..." statement, then the compiler dont know
a-priori if its local or global, so it search X in both namespaces.
Is this a problem of the traceback procedure or the IDE,
or is Python not completely an interpreter, that reads line by line ???
Its compiled to buyte-code then interpreted from the byte-code.
>
Please explain this to me.

thanks,
Stef Mientki
A+

Laurent.
Aug 14 '07 #3
On 2007-08-14, stef mientki <st**********@gmail.comwrote:
I've thought many times I finally understood the import /
namespace rules, but again I'm totally lost :-(

This is my library file

# Module lib_test.py

X = 1

def Init():
global X
X = 3
print 'Init', X

def Run ():
print X <=== UnboundLocalError: local variable
'X' referenced before assignment
X = X + 1
print ' Run', X
From _Python Language Reference Manual_ see: '4.1 Naming and
Binding' and '6.13 The global statement'.

If a name is bound [assigned] in a block, it is a local
variable of that block.

...

The global statement is a declaration which holds for the
entire current code block. It means that the listed identifiers
are to be interpreted as globals. It would be impossible to
assign to a global variable without global, although free
variables may refer to globals without being declared global.

Since your Init and Run functions both assign (bind) a value to
X, X is assumed to be a local variable unless you say otherwise
with a global statement.

Note that the global statement in Init applies only in Init's
code block. Run must have it's own 'global X' statement, if
applicable.

--
Neil Cerutti
Aug 14 '07 #4
stef mientki <st**********@gmail.comwrote:
def Run ():
print X <=== UnboundLocalError: local variable
'X' referenced before assignment
X = X + 1

Why do I get the error ?
Printing isn't assigning anything or am I missing something.
Now if I remove "X = X + 1" I don't get an error ???
Several people have already explained the scoping rules acting
here, but let's just look at how that error message is telling
you everything you need to know to fix the problem.

"local variable 'X' referenced before assignment"

"local variable 'X'" immediately tells you that the 'X' in
question is not your global 'X'.

"referenced before assignment": well, 'print X' is surely a
reference to 'X', and 'X = X + 1' is an assignment to it,
and 'print X' appears before 'X = X + 1'. That this is the
key you have confirmed experimentally.

The question to ask here is "Why does Python think 'X' is
local?" Everything else is answered by the error message.

--
\S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
"Frankly I have no feelings towards penguins one way or the other"
-- Arthur C. Clarke
her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump
Aug 14 '07 #5
Sion Arrowsmith wrote:
stef mientki <st**********@gmail.comwrote:
> def Run ():
print X <=== UnboundLocalError: local variable
'X' referenced before assignment
X = X + 1

Why do I get the error ?
Printing isn't assigning anything or am I missing something.
Now if I remove "X = X + 1" I don't get an error ???

Several people have already explained the scoping rules acting
here, but let's just look at how that error message is telling
you everything you need to know to fix the problem.

"local variable 'X' referenced before assignment"

"local variable 'X'" immediately tells you that the 'X' in
question is not your global 'X'.

"referenced before assignment": well, 'print X' is surely a
reference to 'X', and 'X = X + 1' is an assignment to it,
and 'print X' appears before 'X = X + 1'. That this is the
key you have confirmed experimentally.

The question to ask here is "Why does Python think 'X' is
local?" Everything else is answered by the error message.

Thanks guys, I beginning to see the light again,
and if X is mutual the story is completely different,
I still have to get used to these differences.

cheers,
Stef Mientki

Aug 14 '07 #6
Thanks guys, I beginning to see the light again,
and if X is mutual the story is completely different,
I still have to get used to these differences.
<nitpicking-for-the-sake-of-the-casual-reader>

That's supposed to be "mutable", not "mutual".

</nitpicking-for-the-sake-of-the-casual-reader>

Diez
Aug 14 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

11 posts views Thread by James Gregory | last post: by
145 posts views Thread by Sidney Cadot | last post: by
33 posts views Thread by Snis Pilbor | last post: by
3 posts views Thread by Keith Willis | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.