Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > python newbie - question about lexical scoping

Reply
Thread Tools

python newbie - question about lexical scoping

 
 
Matt Barnicle
Guest
Posts: n/a
 
      12-01-2007
hi everyone.. i've been chugging along learning python for a few months
now and getting answers to all needed questions on my own, but this one
i can't figure out nor can i find information on the internet about it,
possibly because i don't understand the right words to type into google..

i have a very common scenario and need to know the python way to do it.
take this example loop:

comments = []
for row in rows:
comment = models.comment()
comment.author = row[1]
comment.text = row[0]
comments.append(comment)

the problem is that when i go to retrieve the comments later, they are
all the same object! i assume this is due to there being no lexical
scoping? so what is the solution to this?

thank u all!

- m@
 
Reply With Quote
 
 
 
 
John Machin
Guest
Posts: n/a
 
      12-01-2007
On Dec 1, 4:47 pm, Matt Barnicle <ma...@wageslavery.org> wrote:
> hi everyone.. i've been chugging along learning python for a few months
> now and getting answers to all needed questions on my own, but this one
> i can't figure out nor can i find information on the internet about it,
> possibly because i don't understand the right words to type into google..
>
> i have a very common scenario and need to know the python way to do it.
> take this example loop:
>
> comments = []
> for row in rows:
> comment = models.comment()


Insert here:
print type(comment), id(comment), repr(row[:2])

> comment.author = row[1]
> comment.text = row[0]
> comments.append(comment)
>
> the problem is that when i go to retrieve the comments later, they are
> all the same object! i assume this is due to there being no lexical
> scoping? so what is the solution to this?


And the attributes of the "same object" match the first two elements
of which input row:
(a) rows[0]
(b) rows[-1]
(c) some other row
(d) you can't tell because all input rows have the same value in each
of row[0] and row[1]
(e) none of the above?

It's nothing to do with lexical scoping, at least in the code that
you've shown us, which has no apparent problems. You need to show us
the code for the models.comment function/method/class. Possibly it is
returning the same object each time it is invoked (answer (b) above);
the above print statement will help investigate that possibility, plus
the possibility that the objects are not the same objects, but are
different objects with the same attributes (answer (d) above). Also
show us the code for retrieving the comments later; possibly you are
retrieving the same element of the comments list each time. Use this:
print [id(x) for x in comments]
to verify your assertion that they are all the same object.

Cheers,
John

 
Reply With Quote
 
 
 
 
Matt Barnicle
Guest
Posts: n/a
 
      12-02-2007
> On Dec 1, 4:47 pm, Matt Barnicle <ma...@wageslavery.org> wrote:
>> hi everyone.. i've been chugging along learning python for a few months
>> now and getting answers to all needed questions on my own, but this one
>> i can't figure out nor can i find information on the internet about it,
>> possibly because i don't understand the right words to type into
>> google..
>>
>> i have a very common scenario and need to know the python way to do it.
>> take this example loop:
>>
>> comments = []
>> for row in rows:
>> comment = models.comment()

>
> Insert here:
> print type(comment), id(comment), repr(row[:2])
>
>> comment.author = row[1]
>> comment.text = row[0]
>> comments.append(comment)
>>
>> the problem is that when i go to retrieve the comments later, they are
>> all the same object! i assume this is due to there being no lexical
>> scoping? so what is the solution to this?

>
> And the attributes of the "same object" match the first two elements
> of which input row:
> (a) rows[0]
> (b) rows[-1]
> (c) some other row
> (d) you can't tell because all input rows have the same value in each
> of row[0] and row[1]
> (e) none of the above?
>
> It's nothing to do with lexical scoping, at least in the code that
> you've shown us, which has no apparent problems. You need to show us
> the code for the models.comment function/method/class. Possibly it is
> returning the same object each time it is invoked (answer (b) above);
> the above print statement will help investigate that possibility, plus
> the possibility that the objects are not the same objects, but are
> different objects with the same attributes (answer (d) above). Also
> show us the code for retrieving the comments later; possibly you are
> retrieving the same element of the comments list each time. Use this:
> print [id(x) for x in comments]
> to verify your assertion that they are all the same object.
>
> Cheers,
> John


aye yaye aye... thanks for the pointers in the right direction.. i
fiddled around with the code for a while and now i've reduced it to the
*real* issue... i have a class dict variable that apparently holds its
value across instantiations of new objects.. the problem can be
illustrated in the following much simpler code:

>>> class foo():

.... bar = { 'baz': 'bing' }
....
>>> a = foo()
>>> a.bar

{'baz': 'bing'}
>>> a.bar['baz'] = 'bong'
>>> a.bar

{'baz': 'bong'}
>>> b = foo()
>>> b.bar

{'baz': 'bong'}


 
Reply With Quote
 
Matt Barnicle
Guest
Posts: n/a
 
      12-02-2007
> On Dec 1, 4:47 pm, Matt Barnicle <ma...@wageslavery.org> wrote:
>> hi everyone.. i've been chugging along learning python for a few months
>> now and getting answers to all needed questions on my own, but this one
>> i can't figure out nor can i find information on the internet about it,
>> possibly because i don't understand the right words to type into
>> google..
>>
>> i have a very common scenario and need to know the python way to do it.
>> take this example loop:
>>
>> comments = []
>> for row in rows:
>> comment = models.comment()

>
> Insert here:
> print type(comment), id(comment), repr(row[:2])
>
>> comment.author = row[1]
>> comment.text = row[0]
>> comments.append(comment)
>>
>> the problem is that when i go to retrieve the comments later, they are
>> all the same object! i assume this is due to there being no lexical
>> scoping? so what is the solution to this?

>
> And the attributes of the "same object" match the first two elements
> of which input row:
> (a) rows[0]
> (b) rows[-1]
> (c) some other row
> (d) you can't tell because all input rows have the same value in each
> of row[0] and row[1]
> (e) none of the above?
>
> It's nothing to do with lexical scoping, at least in the code that
> you've shown us, which has no apparent problems. You need to show us
> the code for the models.comment function/method/class. Possibly it is
> returning the same object each time it is invoked (answer (b) above);
> the above print statement will help investigate that possibility, plus
> the possibility that the objects are not the same objects, but are
> different objects with the same attributes (answer (d) above). Also
> show us the code for retrieving the comments later; possibly you are
> retrieving the same element of the comments list each time. Use this:
> print [id(x) for x in comments]
> to verify your assertion that they are all the same object.
>
> Cheers,
> John


aye yaye aye... thanks for the pointers in the right direction.. i
fiddled around with the code for a while and now i've reduced it to the
*real* issue... i have a class dict variable that apparently holds its
value across instantiations of new objects.. the problem can be
illustrated in the following much simpler code:

>>> class foo():

.... bar = { 'baz': 'bing' }
....
>>> a = foo()
>>> a.bar

{'baz': 'bing'}
>>> a.bar['baz'] = 'bong'
>>> a.bar

{'baz': 'bong'}
>>> b = foo()
>>> b.bar

{'baz': 'bong'}


 
Reply With Quote
 
Tim Roberts
Guest
Posts: n/a
 
      12-02-2007
Matt Barnicle <> wrote:

>hi everyone.. i've been chugging along learning python for a few months
>now and getting answers to all needed questions on my own, but this one
>i can't figure out nor can i find information on the internet about it,
>possibly because i don't understand the right words to type into google..
>
>i have a very common scenario and need to know the python way to do it.
>take this example loop:
>
>comments = []
>for row in rows:
> comment = models.comment()
> comment.author = row[1]
> comment.text = row[0]
> comments.append(comment)
>
>the problem is that when i go to retrieve the comments later, they are
>all the same object! i assume this is due to there being no lexical
>scoping? so what is the solution to this?


Is that REALLY what the code looks like? Or does it actually look like
this:

comments = []
comment = models.comment()
for row in rows:
comment.author = row[1]
comment.text = row[0]
comments.append(comment)

That construct would produce exactly the result you describe. You would
also get the result you describe if models.comment() were a normal function
that returns a single object, instead of a class name, as I have assumed.
--
Tim Roberts,
Providenza & Boekelheide, Inc.
 
Reply With Quote
 
Matt Barnicle
Guest
Posts: n/a
 
      12-02-2007
>> On Dec 1, 4:47 pm, Matt Barnicle <ma...@wageslavery.org> wrote:
> aye yaye aye... thanks for the pointers in the right direction.. i
> fiddled around with the code for a while and now i've reduced it to the
> *real* issue... i have a class dict variable that apparently holds its
> value across instantiations of new objects.. the problem can be
> illustrated in the following much simpler code:
>
>>>> class foo():

> ... bar = { 'baz': 'bing' }
> ...
>>>> a = foo()
>>>> a.bar

> {'baz': 'bing'}
>>>> a.bar['baz'] = 'bong'
>>>> a.bar

> {'baz': 'bong'}
>>>> b = foo()
>>>> b.bar

> {'baz': 'bong'}


ok, i see... python has a concept i'm not accustomed to which i found
described here:

http://zephyrfalcon.org/labs/python_pitfalls.html
4. Class attributes vs instance attributes

so i'm sure what is going on is obvious to experienced python
programmers... i'm not really sure how to get around this though. i'll
need to spend some time on reworking our models code i guess... i
inherited this from someone, and what he was trying to do was to set
default values for objects representing tables (in kind of a simple ORM
layer) and storing the values in a dict, and when the object is
instantiated, the table is queried and the default dict values are
overwritten. so obviously this method is not going to work as such..

sorry for the misdirection, i didn't quite understand at first..

- m@

 
Reply With Quote
 
Matt Barnicle
Guest
Posts: n/a
 
      12-02-2007
>> On Dec 1, 4:47 pm, Matt Barnicle <ma...@wageslavery.org> wrote:
> aye yaye aye... thanks for the pointers in the right direction.. i
> fiddled around with the code for a while and now i've reduced it to the
> *real* issue... i have a class dict variable that apparently holds its
> value across instantiations of new objects.. the problem can be
> illustrated in the following much simpler code:
>
>>>> class foo():

> ... bar = { 'baz': 'bing' }
> ...
>>>> a = foo()
>>>> a.bar

> {'baz': 'bing'}
>>>> a.bar['baz'] = 'bong'
>>>> a.bar

> {'baz': 'bong'}
>>>> b = foo()
>>>> b.bar

> {'baz': 'bong'}


ok, i see... python has a concept i'm not accustomed to which i found
described here:

http://zephyrfalcon.org/labs/python_pitfalls.html
4. Class attributes vs instance attributes

so i'm sure what is going on is obvious to experienced python
programmers... i'm not really sure how to get around this though. i'll
need to spend some time on reworking our models code i guess... i
inherited this from someone, and what he was trying to do was to set
default values for objects representing tables (in kind of a simple ORM
layer) and storing the values in a dict, and when the object is
instantiated, the table is queried and the default dict values are
overwritten. so obviously this method is not going to work as such..

sorry for the misdirection, i didn't quite understand at first..

- m@

 
Reply With Quote
 
Hrvoje Niksic
Guest
Posts: n/a
 
      12-02-2007
"Matt Barnicle" <> writes:

>> i have a class dict variable that apparently holds its value across
>> instantiations of new objects..

[...]
> ok, i see... python has a concept i'm not accustomed to


I don't doubt that Python managed to confuse you here, but in this
case there is nothing really unusual or novel in Python's treatment of
class variables. Equivalent Java code would behave exactly the same:

class Foo {
static Map bar = new HashMap();
static {
bar.put("baz", "bing");
}
}

Foo a = new Foo();
a.bar.put("baz", "bong");

Foo b = new Foo();
System.out.println(b.bar.get("baz"));
-> "bong"

> so i'm sure what is going on is obvious to experienced python
> programmers... i'm not really sure how to get around this though.


Simply do what you'd do in any other OO language: assign a fresh value
to each instance in its constructor:

class Foo(object):
def __init__(self):
self.bar = {'baz': 'bing'}

Now each instance of Foo has a separate "bar" attribute dict which can
be mutated without affecting other instances.
 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      12-02-2007
Matt Barnicle a écrit :
>>>On Dec 1, 4:47 pm, Matt Barnicle <ma...@wageslavery.org> wrote:

>>
>>aye yaye aye... thanks for the pointers in the right direction.. i
>>fiddled around with the code for a while and now i've reduced it to the
>>*real* issue... i have a class dict variable that apparently holds its
>>value across instantiations of new objects..


If it's a class attribute, it's indeed shared between all instances...

>> the problem can be
>>illustrated in the following much simpler code:
>>
>>>>>class foo():

>>
>>... bar = { 'baz': 'bing' }

(snip)
> ok, i see... python has a concept i'm not accustomed to which i found
> described here:
>
> http://zephyrfalcon.org/labs/python_pitfalls.html
> 4. Class attributes vs instance attributes
>
> so i'm sure what is going on is obvious to experienced python
> programmers... i'm not really sure how to get around this though.


It's not a problem:

class Foo(object):
def __init__(self):
self.bar = {'baz':'bing'}



>i'll
> need to spend some time on reworking our models code i guess... i
> inherited this from someone, and what he was trying to do was to set
> default values for objects representing tables (in kind of a simple ORM
> layer) and storing the values in a dict, and when the object is
> instantiated, the table is queried and the default dict values are
> overwritten.


class Foo(object):
bar = {'baz':'bing'}
def __init__(self):
self.bar = self.bar
 
Reply With Quote
 
hdante
Guest
Posts: n/a
 
      12-02-2007
On Dec 1, 11:31 pm, "Matt Barnicle" <ma...@wageslavery.org> wrote:
> >> On Dec 1, 4:47 pm, Matt Barnicle <ma...@wageslavery.org> wrote:

> > aye yaye aye... thanks for the pointers in the right direction.. i
> > fiddled around with the code for a while and now i've reduced it to the
> > *real* issue... i have a class dict variable that apparently holds its
> > value across instantiations of new objects.. the problem can be
> > illustrated in the following much simpler code:

>
> >>>> class foo():

> > ... bar = { 'baz': 'bing' }
> > ...
> >>>> a = foo()
> >>>> a.bar

> > {'baz': 'bing'}
> >>>> a.bar['baz'] = 'bong'
> >>>> a.bar

> > {'baz': 'bong'}
> >>>> b = foo()
> >>>> b.bar

> > {'baz': 'bong'}

>
> ok, i see... python has a concept i'm not accustomed to which i found
> described here:
>
> http://zephyrfalcon.org/labs/python_pitfalls.html
> 4. Class attributes vs instance attributes
>
> so i'm sure what is going on is obvious to experienced python
> programmers... i'm not really sure how to get around this though. i'll
> need to spend some time on reworking our models code i guess... i
> inherited this from someone, and what he was trying to do was to set
> default values for objects representing tables (in kind of a simple ORM
> layer) and storing the values in a dict, and when the object is
> instantiated, the table is queried and the default dict values are
> overwritten. so obviously this method is not going to work as such..
>
> sorry for the misdirection, i didn't quite understand at first..
>
> - m@



A trivial solution:

class foo:
default_bar = { 'baz' : 'bong' }
def __init__(self):
self.bar = self.default_bar.copy()
self.bar['woo'] = 'wee'

Note: it's not necessary to reimplement an ORM. Try using Django (if
you need a complete solution) or Elixir (just the ORM).
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
FAQ 7.17 What's the difference between dynamic and lexical (static) scoping? Between local() and my()? PerlFAQ Server Perl Misc 0 01-06-2011 05:00 PM
Why no lexical scoping for a method within a class? walterbyrd Python 16 12-18-2008 01:15 AM
C closures & lexical scoping Khookie C Programming 28 12-15-2007 10:50 PM
Lexical scoping question. Louis. Perl Misc 8 02-11-2005 03:45 AM
(?{..}) and lexical scoping issues. Aronaxis, the Sourceror Perl Misc 3 06-21-2004 10:04 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57