473,701 Members | 2,882 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Confused by Python and nested scoping (2.4.3)

Hi. I'm new to Python, and downloaded a Windows copy a little while
ago. I was doing some experiments with nested functions, and ran into
something strange.

This code:

def outer():
val = 10
def inner():
print val
inner()

outer()

...prints out the value '10', which is what I was expecting.

But this code..

def outer():
val = 10
def inner():
print val
val = 20
inner()
print val

outer()

...I expected to print '10', then '20', but instead got an error:

print val
UnboundLocalErr or: local variable 'val' referenced before assignment.

I'm thinking this is some bug where the interpreter is getting ahead of
itself, spotting the 'val = 20' line and warning me about something that
doesn't need warning. Or am I doing something wrong?

Thanks,
-Sean Givan
Apr 19 '06 #1
8 1487
There are only two scopes in Python -- global scope and function scope.

On 4/19/06, Sean Givan <ki*****@nbnet. nb.ca> wrote:
Hi. I'm new to Python, and downloaded a Windows copy a little while
ago. I was doing some experiments with nested functions, and ran into
something strange.

This code:

def outer():
val = 10
def inner():
print val
inner()

outer()

..prints out the value '10', which is what I was expecting.

But this code..

def outer():
val = 10
def inner():
print val
val = 20
inner()
print val

outer()

..I expected to print '10', then '20', but instead got an error:

print val
UnboundLocalErr or: local variable 'val' referenced before assignment.

I'm thinking this is some bug where the interpreter is getting ahead of
itself, spotting the 'val = 20' line and warning me about something that
doesn't need warning. Or am I doing something wrong?

Thanks,
-Sean Givan
--
http://mail.python.org/mailman/listinfo/python-list

--
Kelvie
Apr 19 '06 #2
Sean Givan wrote:
def outer():
val = 10
def inner():
print val
val = 20
inner()
print val

outer()

..I expected to print '10', then '20', but instead got an error:

print val
UnboundLocalErr or: local variable 'val' referenced before assignment.

I'm thinking this is some bug where the interpreter is getting ahead of
itself, spotting the 'val = 20' line and warning me about something that
doesn't need warning. Or am I doing something wrong?

Short answer: No, it's not a Python bug. If inner() must modify
variables defined in outer()'s scope, you'll need to use a containing
object. E.g.:

class Storage(object) :
pass
def outer():
data = Storage()
data.val = 10
def inner():
print data.val
data.val = 20
inner()
print data.val

Long answer:

The interpreter (actually, the bytecode compiler) is indeed looking
ahead. This is by design, and is why the "global" keyword exists. See
http://www.python.org/doc/faq/progra...bles-in-python

Things get more complex than that when nested function scopes are
involved. But again, the behavior you observed is a design decision,
not a bug. By BDFL declaration, there is no "parentscop e" keyword
analogous to "global". See PEP 227, specifically the "Rebinding names
in enclosing scopes" section: http://www.python.org/dev/peps/pep-0227/

Hope that helps,
--Ben

Apr 20 '06 #3
Sean Givan schrieb:
Hi. I'm new to Python
welcome
ago. I was doing some experiments with nested functions, and ran into
something strange.

This code:

def outer():
val = 10
def inner():
print val
inner()

outer()

...prints out the value '10', which is what I was expecting.

But this code..

def outer():
val = 10
def inner():
print val
val = 20
inner()
print val

outer()

...I expected to print '10', then '20', but instead got an error:

print val
UnboundLocalErr or: local variable 'val' referenced before assignment.

I'm thinking this is some bug where the interpreter is getting ahead of
itself, spotting the 'val = 20' line and warning me about something that
just a little carefull thought
if something that basic should really be a bug
how many thousand people would discover it daily?
doesn't need warning. Or am I doing something wrong?


yes, you can't modify it
you can do it for global namespace or local
but not inbetween

val = 0
def outer():
val = 10
def inner():
global val
val = 30
inner()
print val
outer()
10 # outer val is not changed
print val # global is modified
30

hth, Daniel

Apr 20 '06 #4

"Sean Givan" <ki*****@nbnet. nb.ca> wrote in message
news:AG******** *************@u rsa-nb00s0.nbnet.nb .ca...
Hi. I'm new to Python, and downloaded a Windows copy a little while
ago. I was doing some experiments with nested functions, and ran into
something strange. Experiments are good. Strange can be instructive.
.... I'm thinking this is some bug Blaming the interpreter is not so good, but amazingly common among
newcomers ;-)
where the interpreter is getting ahead of itself, .... Or am I doing something wrong?


In a sense, you got ahead of yourself. And the issue has nothing to do
with nested scopes per se. When things seem strange, try a simpler
experiment.
x=1
def f(): print x
x = 2
f()

Traceback (most recent call last):
File "<pyshell#5 >", line 1, in -toplevel-
f()
File "<pyshell#4 >", line 2, in f
print x
UnboundLocalErr or: local variable 'x' referenced before assignment

The compiler compiles functions in two passes: the first to classify names
as local or global (or nested if relevant, but not really so here), the
second to generate bytecodes which depend on that classification.

Terry Jan Reedy

Apr 20 '06 #5
Sean Givan wrote:
Hi. I'm new to Python, and downloaded a Windows copy a little while
ago. I was doing some experiments with nested functions, and ran into
something strange.

This code:

def outer():
val = 10
def inner():
print val
inner()

outer()

..prints out the value '10', which is what I was expecting.

But this code..

def outer():
val = 10
def inner():
print val
val = 20
inner()
print val

outer()

..I expected to print '10', then '20', but instead got an error:

print val
UnboundLocalErr or: local variable 'val' referenced before assignment.

I'm thinking this is some bug where the interpreter is getting ahead of
itself, spotting the 'val = 20' line and warning me about something that
doesn't need warning. Or am I doing something wrong?


reading the reference documentation may help:

http://docs.python.org/ref/naming.html

"If a name binding operation occurs anywhere within a code block,
all uses of the name within the block are treated as references to
the current block."

</F>

Apr 20 '06 #6
I have added some spaces guessing how the original was formatted.
See the simplified example and the explanation below...

"Sean Givan" wrote...
Hi. I'm new to Python [...] something strange.
This code:

def outer():
val = 10
def inner():
print val
inner()
outer()

..prints out the value '10', which is what I was expecting.

But this code..
def outer():
val = 10
def inner():
print val
val = 20
inner()
print val
outer()

..I expected to print '10', then '20', but instead got an error:

print val
UnboundLocalErr or: local variable 'val' referenced before assignment.

I'm thinking this is some bug where the interpreter is getting ahead of
itself, spotting the 'val = 20' line and warning me about something that
doesn't need warning. Or am I doing something wrong?


The simplified example of both cases can be
script a.py
---------------------------------------------
val = 10

def myFunction():
print val

myFunction()
---------------------------------------------

In this case the val is not defined inside myFunction();
therefore, it is searched in the "upper level", above
the function body. Such variable is called free variable.

script b.py
---------------------------------------------
val = 10

def myFunction():
print val
val = 20

myFunction()

---------------------------------------------

In this case the val is assigned inside the myFunction()
and it is not marked to be global. In this case Python
decides that it will be the local variable (cannot be
free variable anymore). Python insists on fact that
in one block the variable can be or free or locally
bound, but not both. This is decided during the
compilation of the module and it does not depend
on whether val = 20 assignment precedes the print val
command or not. It is decided that it will be local
inside myFunction and then the print wants to use
the variable that was not assingned yet.

pepr

P.S. I have just noticed that Terry Jan Reedy answered
similarly. Never mind... Repeat, repeat, repeat.... until
you know ;)
Apr 20 '06 #7
Kelvie Wong wrote:
There are only two scopes in Python -- global scope and function scope.


No, Python has local, nested, global and built-in scope.

Kent
Apr 20 '06 #8
>> P.S. I have just noticed that Terry Jan Reedy answered
similarly. Never mind... Repeat, repeat, repeat.... until
you know ;)


Yes, and some of us appreciate the extra examples.

rick

Apr 20 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3859
by: Rob Hunter | last post by:
Is there an equivalent to Scheme's LET in Python? LET creates a new binding in the current environment. For example, here's some Scheme code: (let ((x 3)) (let ((f (lambda (arg) (* arg x)))) (let ((x 4)) (f 5))))
7
2054
by: Max | last post by:
Yeah, I know. It's the price we pay for forsaking variable declarations. But for java programmers like me, Py's scoping is too complicated. Please explain what constitutes a block/namespace, and how to refer to variables outside of it.
4
1642
by: kj | last post by:
I'm a Perlhead (there, I said it). Years ago I made a genuine attempt to learn Python, but my intense disappointed with the way Python deals with scopes ultimately sapped my enthusiasm. I couldn't live without closures and without the fine control over scopes that Perl provides. I've been wanting to make another attempt to (re)learn Python for a while, but this scopes business remained a major damper. What's pushing me over my...
134
6085
by: Joseph Garvin | last post by:
As someone who learned C first, when I came to Python everytime I read about a new feature it was like, "Whoa! I can do that?!" Slicing, dir(), getattr/setattr, the % operator, all of this was very different from C. I'm curious -- what is everyone's favorite trick from a non-python language? And -- why isn't it in Python? Here's my current candidate: So the other day I was looking at the language Lua. In Lua, you make a
2
3652
by: Robert M. Gary | last post by:
I'm curious what the ANSI C++ standard says about nested classes. I'm not able to find where in the ANSI C++ standard this is addressed. The issue is the accessibility of sibling nested classes. Example... class A{ private: class B{ }; class C{
13
3019
by: Chris Carlen | last post by:
Hi: I have begun learning Python by experimenting with the code snippets here: http://hetland.org/writing/instant-python.html In the section on functions, Magnus Lie Hetland writes: -------------------------------------------------------------------- For those of you who understand it: When you pass a parameter to a
22
7908
by: Kurien Mathew | last post by:
Hello, Any suggestions on a good python equivalent for the following C code: while (loopCondition) { if (condition1) goto next; if (condition2) goto next;
0
8738
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8649
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9233
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9085
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
6575
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5905
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4411
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3104
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2036
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.