473,804 Members | 3,034 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Weird behavior with lexical scope

I ran into a weird behavior with lexical scope in Python. I'm hoping
someone on this forum can explain it to me.

Here's the situation: I have an Outer class. In the Outer class, I
define a nested class 'Inner' with a simple constructor. Outer's
constructor creates an instance of Inner. The code looks like this:

=========
class Outer:
class Inner:
def __init__(self):
pass
def __init__ (self):
a = Inner()
Outer()
=========

However, the above code doesn't work. The creation of Inner() fails.
The error message looks like this:

File "/tmp/foo.py", line 12, in <module>
Outer()
File "/tmp/foo.py", line 10, in __init__
a = Inner()
NameError: global name 'Inner' is not defined

This surprises me! Since the construction of Inner takes place within
the lexical scope 'Outer', I assumed the interpreter would search the
Outer scope and find the 'Inner' symbol. But it doesn't! If I change:
a = Inner()
to
a = Outer.Inner()

it works fine, though.

So, can anyone explain to me how Python looks up symbols? It doesn't
seem to be searching the scopes I expected...

Thanks,
--Steve
Nov 6 '08 #1
9 1732
mrstevegross <mr**********@g mail.comwrites:
I ran into a weird behavior with lexical scope in Python. I'm hoping
someone on this forum can explain it to me.

Here's the situation: I have an Outer class. In the Outer class, I
define a nested class 'Inner' with a simple constructor. Outer's
constructor creates an instance of Inner. The code looks like this:

=========
class Outer:
class Inner:
def __init__(self):
pass
def __init__ (self):
a = Inner()
Outer()
=========

However, the above code doesn't work. The creation of Inner() fails.
This is because there isn't lexical scoping in class scopes.

Try replacing

a = Inner()

with

a = Outer.Inner()
Alternatively,

class Outer:
class Inner:
...
def __init__(self, Inner=Inner):
a = Inner()

HTH

--
Arnaud
Nov 6 '08 #2
def __init__(self, Inner=Inner):

Ok, the Inner=Inner trick works. What the heck does that do, anyway?
I've never seen that formulation.

--Steve
Nov 6 '08 #3
I want to write a Vector class and it makes the most sense to just subclasslist. I also want to be able to instantiate a vector using either:

Vector( 1, 2, 3 )
OR
Vector( [1, 2, 3] )
so I have this:

class Vector(list):
def __new__( cls, *a ):
try:
print a
return list.__new__(cl s, a)
except:
print 'broken'
return list.__new__(cl s, list(a))
doing Vector( 1, 2, 3 ) on this class results in a TypeError - which doesn't seem to get caught by the try block (ie "broken" never gets printed, and it never tries to

I can do pretty much the exact same code but inheriting from tuple instead of list and it works fine.

is this a python bug? or am I doing something wrong?

thanks,
-h.
Nov 6 '08 #4
>def __init__(self, Inner=Inner):
SteveOk, the Inner=Inner trick works. What the heck does that do, anyway?
SteveI've never seen that formulation.

Understanding that will put you on the path to scoping enlightenment.
Consider when that default assignment is established and how that might
differ from the assignment that occurs when __init__ is called.

Skip

Nov 6 '08 #5
At 2008-11-06T16:57:39Z, mrstevegross <mr**********@g mail.comwrites:
class Outer:
class Inner:
def __init__(self):
pass
def __init__ (self):
a = Inner()
Outer()
Try instead:

class Outer:
def __init__(self):
a = self.Inner()
--
Kirk Strauser
The Day Companies
Nov 6 '08 #6
On Nov 6, 9:57*pm, mrstevegross <mrstevegr...@g mail.comwrote:
I ran into a weird behavior with lexical scope in Python. I'm hoping
someone on this forum can explain it to me.

Here's the situation: I have an Outer class. In the Outer class, I
define a nested class 'Inner' with a simple constructor. Outer's
constructor creates an instance of Inner. The code looks like this:

=========
class Outer:
* class Inner:
* * def __init__(self):
* * * pass
* def __init__ (self):
* * a = Inner()
Outer()
=========

However, the above code doesn't work. The creation of Inner() fails.
The error message looks like this:

* File "/tmp/foo.py", line 12, in <module>
* * Outer()
* File "/tmp/foo.py", line 10, in __init__
* * a = Inner()
NameError: global name 'Inner' is not defined

This surprises me! Since the construction of Inner takes place within
the lexical scope 'Outer', I assumed the interpreter would search the
Outer scope and find the 'Inner' symbol. But it doesn't! If I change:
* a = Inner()
to
* a = Outer.Inner()

it works fine, though.
AFAIK, when 'Outer.__init__ ' executes, 'Inner' is first searched for
within 'Outer.__init__ ()'s local namespace. Since 'Inner' is defined
outside the function namespace, the search will fail. Python then
looks at the module level namespace - where Inner is again not defined
(only 'Outer' is available in the module namespace), the final search
will be in the interpreter global namespace which will fail too. When
you change your code from 'Inner' to 'Outer.Inner', the module level
namespace search will match ( or atleast that's how i think it should
all work :) )

Try this ..

class Outer:
def __init__(self):
class Inner:
def __init__(self): pass
a = Inner()
Outer()

This should work, because the Outer.__init__ namespace (first
namespace being searched) has Inner defined within it

-srp
>
So, can anyone explain to me how Python looks up symbols? It doesn't
seem to be searching the scopes I expected...

Thanks,
--Steve
Nov 6 '08 #7
Hamish McKenzie <ha****@valveso ftware.comwrite s:
I want to write a Vector class and it makes the most sense to just
subclass list. I also want to be able to instantiate a vector using
either:

Vector( 1, 2, 3 )
OR
Vector( [1, 2, 3] )
so I have this:

class Vector(list):
def __new__( cls, *a ):
try:
print a
return list.__new__(cl s, a)
except:
print 'broken'
return list.__new__(cl s, list(a))
doing Vector( 1, 2, 3 ) on this class results in a TypeError - which
doesn't seem to get caught by the try block (ie "broken" never gets
printed, and it never tries to

I can do pretty much the exact same code but inheriting from tuple
instead of list and it works fine.

is this a python bug? or am I doing something wrong?
You're doing something wrong!

When you call Vector.__new__( cls, *a), this creates a new list object
(call it L) and then calls Vector.__init__ (L, *a) automatically, falling
back to list.__init__(L , *a) (which won't work when a has more than one
element). In fact list initialisation is done in list.__init__, not in
list.__new__ (as opposed to tuple initialisation because tuples are
immutable).

A solution:
>>class Vector(list):
.... def __init__(self, *args):
.... try:
.... list.__init__(s elf, *args)
.... except TypeError:
.... list.__init__(s elf, args)
....
>>Vector([1,2,3])
[1, 2, 3]
>>Vector(1,2, 3)
[1, 2, 3]
>>Vector(1)
[1]
>>Vector()
[]

HTH

--
Arnaud
Nov 6 '08 #8
sa*********@gma il.com wrote:
On Nov 6, 9:57 pm, mrstevegross <mrstevegr...@g mail.comwrote:
>I ran into a weird behavior with lexical scope in Python. I'm hoping
someone on this forum can explain it to me.

Here's the situation: I have an Outer class. In the Outer class, I
define a nested class 'Inner' with a simple constructor. Outer's
constructor creates an instance of Inner. The code looks like this:

=========
class Outer:
class Inner:
def __init__(self):
pass
def __init__ (self):
a = Inner()
Outer()
=========

However, the above code doesn't work. The creation of Inner() fails.
The error message looks like this:

File "/tmp/foo.py", line 12, in <module>
Outer()
File "/tmp/foo.py", line 10, in __init__
a = Inner()
NameError: global name 'Inner' is not defined

This surprises me! Since the construction of Inner takes place within
the lexical scope 'Outer', I assumed the interpreter would search the
Outer scope and find the 'Inner' symbol. But it doesn't! If I change:
a = Inner()
to
a = Outer.Inner()

it works fine, though.
So do that.
AFAIK, when 'Outer.__init__ ' executes, 'Inner' is first searched for
within 'Outer.__init__ ()'s local namespace. Since 'Inner' is defined
outside the function namespace, the search will fail. Python then
looks at the module level namespace - where Inner is again not defined
(only 'Outer' is available in the module namespace), the final search
will be in the interpreter global namespace which will fail too. When
Interpreter global namespace == builtins
you change your code from 'Inner' to 'Outer.Inner', the module level
namespace search will match ( or atleast that's how i think it should
all work :) )
Correct
Try this ..
Why?
class Outer:
def __init__(self):
class Inner:
def __init__(self): pass
a = Inner()
This create a duplicate Inner class object for every instance of Outer,
which is almost certainly not what the OP wants.
Outer()

This should work, because the Outer.__init__ namespace (first
namespace being searched) has Inner defined within it
tjr

Nov 6 '08 #9
In message <ma************ *************** ***********@pyt hon.org>, Terry
Reedy wrote:
sa*********@gma il.com wrote:
>class Outer:
def __init__(self):
class Inner:
def __init__(self): pass
a = Inner()

This create a duplicate Inner class object for every instance of Outer,
which is almost certainly not what the OP wants.
Does it matter?
Nov 7 '08 #10

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

Similar topics

7
3047
by: Konrad Den Ende | last post by:
Normally, one can put any bull as long as comments are on, as in: // import yava.biteme.yo_mamma; but when i tried to do //String s = "\u305\u3048"; the stupid computer tells me to shut up by claiming that it's an illegal unicode escape. Now, i've bought it, so i'll tell it what is
3
2308
by: Matt Knepley | last post by:
I must be misunderstanding how Python 2.3 handles lexical scoping. Here is a sample piece of code: def run(): a = 1 def run2(b): print a run2(2) print a run()
11
1962
by: ncf | last post by:
Ok, I've been tring to resolve this issue for some time now (~1 day which is way longer than normal for me) to no avail. I am reading a file into a list in memory, using a "%" delimited file format (which allows for comments on lines beginning with "#"), and some of the messages are not correctly copied. I believe the problem may be somewhere around the strcpy() call, but am not sure at all.
18
1803
by: jslowery | last post by:
I am not completely knowledgable about the status of lexical scoping in Python, but it was my understanding that this was added in a long time ago around python2.1-python2.2 I am using python2.4 and the following code throws a "status variable" not found in the inner-most function, even when I try to "global" it. def collect(fields, reducer): def rule(record): status = True
4
1329
by: Miro | last post by:
Vb2003, im still learning vb.net but I do not understand my output from this logic. If someone can help me out here. Cor Ligthert, you I believe were on the right track of what Im trying to create. -Thank you very much for leading me on to Classes. Ok here is my code. ( see below )
6
2046
by: enaeher | last post by:
I would expect this code: globalFnArray = ; for (var i = 0; i < 5; i++) { globalFnArray.push (function () { alert (i) }); } for (var j = 0; j < 5; j++) { globalFnArray(); } to alert 0, 1, 2, 3, and 4. Instead, I get 5, 5, 5, 5, and 5 in Firefox, indicating that all of
7
1476
by: thamizh.veriyan | last post by:
Hi, I am new to this community. I have a doubt regarding trap representations. I read in IBM's website that something like this is legal: int main(){ int x=3; {
3
8798
by: globalrev | last post by:
i cant figure outif python has lexical or general scope. it seems functions have lexical scope but with some restrictions and some non-function scopes are dynamic?
2
1532
by: Matt Nordhoff | last post by:
Sebastjan Trepca wrote: Python doesn't like when you read a variable that exists in an outer scope, then try to assign to it in this scope. (When you do "a = b", "b" is processed first. In this case, Python doesn't find a "value" variable in this scope, so it checks the outer scope, and does find it. But then when it gets to the "a = " part... well, I don't know, but it doesn't like it.)
0
9704
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
10319
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...
0
9132
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 launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7608
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
6845
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
5508
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
4282
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
2
3803
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2978
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.