473,573 Members | 2,866 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

nested function scopes

hi,

i'm having some trouble nesting functions. consider the following:
def h():
x = 1
def g():
print x # ok, x is taken from h
g()

def f():
x = 1
def g():
print x # this is not ok
x = 2 # this implies that x is local to g
g()

h() # ok
f() # UnboundLocalErr or: local variable 'x' referenced before assignment
when i run this code i get:
1
Traceback (most recent call last):
File "test.py", line 15, in ?
f() # UnboundLocalErr or: local variable 'x' referenced before assignment
File "test.py", line 12, in f
g()
File "test.py", line 10, in g
print x # this is not ok
UnboundLocalErr or: local variable 'x' referenced before assignment
how do i declare that x belongs to the parent function, so that i can do
assignments to it? do i have to put it into a compound object?

it would be very handy to be able to do this if i have nested functions
that use a lot of varables. only passing the variables you assign to as
packed compound parameters is a bit ugly, since what subset of all
variables this is might change.

i cannot say i like the python scope rules yet. they probably are
practical, but they seem complicated an unstructured to me.

take for example
class C:
y = 0
def f(self):
print y
which does not work unless y is a global. i understand and agree too why
y is not taken from the instance (self), because of the way classes and
instances relate in python. what i do not understand, is why y is not
taken from C, but from global, when nothing is specified. in the
previous example, with the functions h() and g(), g() took x from h().
why should not f() take y from C?

klem fra nils

--
nils grimsmo <ni*****@idi.nt nu.no>
"why is this thus? what is the reason of this thusness"
- artemus ward
Jul 18 '05 #1
3 2333
Nils Grimsmo wrote:
i'm having some trouble nesting functions. consider the following:
You understand the rules, I think. You just don't like them. The
appropriate koan is "explicit is better than implicit".

I'd use something like this:

class Struct(object):
pass
...
def outer():
shared = Struct()
shared.counter = 1
def inner():
print 'inner says:', shared.counter
shared.counter += 1
inner()
inner()
print 'outer says:', shared.counter
it would be very handy to be able to do this if i have nested
functions that use a lot of variables. only passing the variables
you assign to as packed compound parameters is a bit ugly,
since what subset of all variables this is might change.
Python's goal is to make code more easy to _read_, not _write_.
I find it easier to read the outer function when I know
what might change on me. As my example shows, you needn't
thread all calls with the list of values.

There is another python idea here you haven't yet caught:
You speak of variables, but python only has associations of
names with values. When you think in terms of names and
associations, you may find 'inner's ability to see what 'outer'
is talking about without being able to affect 'outer's
associations reasonable.
i cannot say i like the python scope rules yet. they probably are
practical, but they seem complicated an unstructured to me. Give it time. They are simple when you twist your head just right,
then they will seem completely simple.
class C:
y = 0
def f(self):
print y
Again, "explicit is better than implicit".

Either:
class D(object):
y = "D's y"
def f(self):
print self.y
Or:
class E(object):
y = "E's y"
def f(self):
print E.y

behave as you wish. Bindings first look to the instance and
then the class. Python is quite dynamic. There is, by the way,
a difference between the two above. Ponder the following two
subclasses:

class F(D):
y = "F(D)'s y"

class G(E):
y = "G(E)'s y"

F().f() prints F(D)'s y
G().f() prints E's y

to work in the same was as the two above, but you'd be wrong.
In the previous example, with the functions h() and g(), g()
why should not f() take y from C?

but which class should it choose in my examples? The instance's
exact class? The class in which the method was defined? You
could mean either, and be without a way to specify the other.

Further, you could do this:
y = "global"
class C:
def f(self):
print y

o = C()
o.f()
C.y = "classs variable"
o.f()

Should the second call to o.f() print something different than
the first one?

Anyhow, this is really too long already. I'll just include the
Struct definition I actually use when coding. It uses too much
magic to be clear, but it prints nicely in interactive mode.

This in my "toys.py":

class Struct(object):
def __init__(self, **kw):
self.__dict__.u pdate(kw)
def __repr__(self):
return '%s(%s)' % (self.__class__ .__name__,
', '.join(['%s=%r' % name_val for
name_val in self.__dict__.i tems()]))

Then (when I want data types):
import toys
class Holder(toys.Str uct): pass # just to give a name

And my example becomes:

def outer():
shared = Holder(counter= 1, name='Fred')
def inner():
print 'inner says:', shared
shared.counter += 1
inner()
inner()
print 'outer says:', shared
-Scott David Daniels
Sc***********@A cm.Org
Jul 18 '05 #2

"Nils Grimsmo" <ni*****@idi.nt nu.no> wrote in message
news:3f******** @news.broadpark .no...
hi,

i'm having some trouble nesting functions. consider the following:
def h():
x = 1
def g():
print x # ok, x is taken from h
g()

def f():
x = 1
def g():
print x # this is not ok
x = 2 # this implies that x is local to g
g()

h() # ok
f() # UnboundLocalErr or: local variable 'x' referenced before assignment .... how do i declare that x belongs to the parent function, so that i can do
assignments to it?
Currently you cannot. As you probably know, 'global' declares that x
belongs to the module so you can assign to as well read it. This fall,
there was an extended discussion on pydev (at least 30 posts, I am sure) on
the subject of extending the idea of global to allow assignment to
intermediate scopes. Would such be desireable? If so, what syntax? See
python.org for B. Cannon's summaries or link to archives. Current bottom
line: no change.
do i have to put it into a compound object?
If compound = mutable collection, yes. Your example revised:

def f():
x = [1]
def g():
print x[0]
x[0] = 2
g()

The ease of doing this and the ugliness or other problems with proposed
alternatives inhibits change.
it would be very handy to be able to do this if i have nested functions
that use a lot of varables. only passing the variables you assign to as
packed compound parameters is a bit ugly, since what subset of all
variables this is might change.
You do not have to 'pass' the compound since you have read access to mutate
it.
i cannot say i like the python scope rules yet. they probably are
practical, but they seem complicated an unstructured to me.
They were simpler before nested scopes were introduced ;-). You can program
without them if you wish.
take for example

class C:
y = 0
def f(self):
print y which does not work unless y is a global. i understand and agree too why
y is not taken from the instance (self), because of the way classes and
instances relate in python. what i do not understand, is why y is not
taken from C, but from global, when nothing is specified. in the
previous example, with the functions h() and g(), g() took x from h().
why should not f() take y from C?


This is a different kettle of fish. Classes, though callable, are not
functions and methods are not nested functions. Neither class nor instance
methods can be called during class construction because neither the class
nor instances thereof even exist. In any case, there is already a mechanism
for accessing class attributes: C.y in this case. Use it.

Terry J. Reedy

Jul 18 '05 #3

Terry Reedy:

Nils Grimsmo:
i'm having some trouble nesting functions. consider the following: [snip] def f():
x = 1
def g():
print x # this is not ok
x = 2 # this implies that x is local to g [snip] how do i declare that x belongs to the parent function, so that i can do assignments to it?


Currently you cannot.


Why not use the old method of passing variables to nested functions:
def f()
x = 1
def g(x=x):
print x
x = 2

Emile van Sebille
em***@fenx.com

Jul 18 '05 #4

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

Similar topics

3
1483
by: Miki Tebeka | last post by:
Hello, Can anyone explain why: >>> def make_inc(n): s = n def inc(i): s += i return s return inc
6
2560
by: Andy Baker | last post by:
Hi there, I'm learning Python at the moment and trying to grok the thinking behind it's scoping and nesting rules. I was googling for nested functions and found this Guido quote: (http://www.python.org/search/hypermail/python-1993/0343.html) "This is because nested function definitions don't have access to the local variables of the...
5
1796
by: Dave Benjamin | last post by:
I ran into an odd little edge case while experimenting with functions that create classes on the fly (don't ask me why): >>> def f(x): ... class C(object): ... x = x ... print C.x ... >>> f(5) Traceback (most recent call last):
7
2242
by: block111 | last post by:
Hello, code like this: int f1(int x){ int f2(int y){ return y*y; } if(x > 0) return f2(x);
8
1482
by: Sean Givan | last post by:
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
37
2754
by: Tim N. van der Leeuw | last post by:
Hi, The following might be documented somewhere, but it hit me unexpectedly and I couldn't exactly find this in the manual either. Problem is, that I cannot use augmented assignment operators in a nested scope, on variables from the outer scope: PythonWin 2.4.3 (#69, Mar 29 2006, 17:35:34) on win32. Portions Copyright 1994-2004 Mark...
78
4916
by: Josiah Manson | last post by:
I found that I was repeating the same couple of lines over and over in a function and decided to split those lines into a nested function after copying one too many minor changes all over. The only problem is that my little helper function doesn't work! It claims that a variable doesn't exist. If I move the variable declaration, it finds the...
2
1654
by: Johannes Bauer | last post by:
Nick Keighley schrieb: Why is there actually a *need* for nested functions? If functionality of subfunctions which are only locally visible is desired, why not put the nesting function parent and its nested children all in one module, declare the children static - voila. Std-C. Regards, Johannes
0
200
by: Maric Michaud | last post by:
Le Tuesday 12 August 2008 11:29:18 Cousson, Benoit, vous avez écrit : This is a language limitation. This is because nested scope is implemented for python function only since 2.3 allow late binding of free variables. the scope in class statment is not a closure, so there is only two possible scope in it : local and global. When "class...
0
8032
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. ...
0
8205
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...
0
8074
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6424
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5294
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...
0
3734
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...
1
2223
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
1
1310
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1044
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...

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.