Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #14856 > unrolled thread
| Started by | Gnarlodious <gnarlodious@gmail.com> |
|---|---|
| First post | 2011-10-22 17:26 -0700 |
| Last post | 2011-10-22 17:55 -0700 |
| Articles | 13 — 10 participants |
Back to article view | Back to comp.lang.python
How to isolate a constant? Gnarlodious <gnarlodious@gmail.com> - 2011-10-22 17:26 -0700
Re: How to isolate a constant? Chris Rebert <clp2@rebertia.com> - 2011-10-22 17:41 -0700
Re: How to isolate a constant? Gnarlodious <gnarlodious@gmail.com> - 2011-10-22 18:01 -0700
Re: How to isolate a constant? 88888 Dihedral <dihedral88888@googlemail.com> - 2011-10-22 22:12 -0700
Re: How to isolate a constant? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-10-23 05:32 +0000
Re: How to isolate a constant? Paul Rudin <paul.nospam@rudin.co.uk> - 2011-10-23 11:23 +0100
Re: How to isolate a constant? MRAB <python@mrabarnett.plus.com> - 2011-10-23 01:46 +0100
Re: How to isolate a constant? Alan Meyer <ameyer2@yahoo.com> - 2011-10-25 15:50 -0400
Re: How to isolate a constant? Ian Kelly <ian.g.kelly@gmail.com> - 2011-10-25 14:05 -0600
Re: How to isolate a constant? Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2011-10-25 17:08 -0700
Re: How to isolate a constant? Mel <mwilson@the-wire.com> - 2011-10-25 22:48 -0400
Re: How to isolate a constant? Ian Kelly <ian.g.kelly@gmail.com> - 2011-10-25 18:30 -0600
Re: How to isolate a constant? Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2011-10-22 17:55 -0700
| From | Gnarlodious <gnarlodious@gmail.com> |
|---|---|
| Date | 2011-10-22 17:26 -0700 |
| Subject | How to isolate a constant? |
| Message-ID | <f5539538-d079-4be1-b2c0-d98d3fc6a33f@h39g2000prh.googlegroups.com> |
Say this: class tester(): _someList = [0, 1] def __call__(self): someList = self._someList someList += "X" return someList test = tester() But guess what, every call adds to the variable that I am trying to copy each time: test() > [0, 1, 'X'] test() > [0, 1, 'X', 'X'] Can someone explain this behavior? And how to prevent a classwide constant from ever getting changed? -- Gnarlie
[toc] | [next] | [standalone]
| From | Chris Rebert <clp2@rebertia.com> |
|---|---|
| Date | 2011-10-22 17:41 -0700 |
| Message-ID | <mailman.2137.1319330487.27778.python-list@python.org> |
| In reply to | #14856 |
On Sat, Oct 22, 2011 at 5:26 PM, Gnarlodious <gnarlodious@gmail.com> wrote: > Say this: > > class tester(): Style note: either have it explicitly subclass `object`, or don't include the parens at all. Empty parens for the superclasses is just weird. > _someList = [0, 1] > def __call__(self): > someList = self._someList > someList += "X" > return someList > > test = tester() > > But guess what, every call adds to the variable that I am trying to > copy each time: > test() >> [0, 1, 'X'] > test() >> [0, 1, 'X', 'X'] > > > Can someone explain this behavior? The line `someList = self._someList` does NOT copy the list. It make `someList` point to the same existing list object. Hence, modifications to that object from either variable will affect the other. Similarly, `someList += "X"` modifies someList *in-place*; it does not produce a new list object. The upshot is that you're just modifying and returning references to *the same list* repeatedly, never producing a new list object. > And how to prevent a classwide > constant from ever getting changed? Python doesn't have any language-enforced notion of constants. So, short of writing/using a library to try and enforce such a notion, you're out of luck. You could use an immutable datatype (e.g. a tuple) instead of a mutable one (e.g. a list) as some level of safeguard though. Cheers, Chris -- http://rebertia.com
[toc] | [prev] | [next] | [standalone]
| From | Gnarlodious <gnarlodious@gmail.com> |
|---|---|
| Date | 2011-10-22 18:01 -0700 |
| Message-ID | <7840d89c-3648-45fe-ae6f-d3bb2ca2abdb@z28g2000pro.googlegroups.com> |
| In reply to | #14857 |
On Oct 22, 6:41 pm, Chris Rebert <c...@rebertia.com> wrote: > The line `someList = self._someList` does NOT copy the list. It make > `someList` point to the same existing list object. Thanks for all those explanations, I've already fixed it with a tuple. Which is more reliable anyway. -- Gnarlie
[toc] | [prev] | [next] | [standalone]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2011-10-22 22:12 -0700 |
| Message-ID | <12317784.900.1319346736804.JavaMail.geo-discussion-forums@prfk19> |
| In reply to | #14860 |
Thank you for the good trick for a static class owned property. Someone might object this but this is really useful.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-10-23 05:32 +0000 |
| Message-ID | <4ea3a707$0$29968$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #14860 |
On Sat, 22 Oct 2011 18:01:52 -0700, Gnarlodious wrote: > On Oct 22, 6:41 pm, Chris Rebert <c...@rebertia.com> wrote: > >> The line `someList = self._someList` does NOT copy the list. It make >> `someList` point to the same existing list object. > Thanks for all those explanations, I've already fixed it with a tuple. > Which is more reliable anyway. No, tuples are not "more reliable" than lists. Don't make the mistake of confusing your inexperience and lack of understanding about Python's object model for "lists are unreliable". They are completely reliable. You just have to learn how they work, and not make invalid assumptions about how they work. You wouldn't say "Nails are more reliable than screws, because I hammered a screw into a plaster wall and it just fell out." Of course it fell out: you used it incorrectly for what you needed. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Paul Rudin <paul.nospam@rudin.co.uk> |
|---|---|
| Date | 2011-10-23 11:23 +0100 |
| Message-ID | <87y5wcj9at.fsf@no-fixed-abode.cable.virginmedia.net> |
| In reply to | #14860 |
Gnarlodious <gnarlodious@gmail.com> writes: > Thanks for all those explanations, I've already fixed it with a tuple. > Which is more reliable anyway. neither of lists or tuples are "more reliable" than the other. They both have perfectly well defined behaviour (which can be gleaned from reading the documentation) and reliably behave as documented. You just have to choose which fits better for the computation you're trying to implement.
[toc] | [prev] | [next] | [standalone]
| From | MRAB <python@mrabarnett.plus.com> |
|---|---|
| Date | 2011-10-23 01:46 +0100 |
| Message-ID | <mailman.2138.1319330815.27778.python-list@python.org> |
| In reply to | #14856 |
On 23/10/2011 01:26, Gnarlodious wrote:
> Say this:
>
> class tester():
> _someList = [0, 1]
> def __call__(self):
> someList = self._someList
> someList += "X"
> return someList
>
> test = tester()
>
> But guess what, every call adds to the variable that I am trying to
> copy each time:
> test()
>> [0, 1, 'X']
> test()
>> [0, 1, 'X', 'X']
>
>
> Can someone explain this behavior? And how to prevent a classwide
> constant from ever getting changed?
>
'_someList' is part of the class itself.
This:
someList = self._someList
just creates a new _reference to the list and this:
someList += "X"
appends the items of the sequence "X" to the list.
Note that a string is also a sequence of characters, so:
>>> x = []
>>> x += "XY"
>>> x
['X', 'Y']
Python will copy something only when you tell it to copy. A simple way
of copying a list is to slice it:
someList = self._someList[:]
[toc] | [prev] | [next] | [standalone]
| From | Alan Meyer <ameyer2@yahoo.com> |
|---|---|
| Date | 2011-10-25 15:50 -0400 |
| Message-ID | <4EA71323.2030500@yahoo.com> |
| In reply to | #14858 |
On 10/22/2011 8:46 PM, MRAB wrote:
> On 23/10/2011 01:26, Gnarlodious wrote:
>> Say this:
>>
>> class tester():
>> _someList = [0, 1]
>> def __call__(self):
>> someList = self._someList
>> someList += "X"
>> return someList
>>
>> test = tester()
>>
>> But guess what, every call adds to the variable that I am trying to
>> copy each time:
>> test()
>>> [0, 1, 'X']
>> test()
>>> [0, 1, 'X', 'X']
...
> Python will copy something only when you tell it to copy. A simple way
> of copying a list is to slice it:
>
> someList = self._someList[:]
And another simple way:
...
someList = list(self._someList)
...
Alan
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2011-10-25 14:05 -0600 |
| Message-ID | <mailman.2215.1319573187.27778.python-list@python.org> |
| In reply to | #14979 |
On Tue, Oct 25, 2011 at 1:50 PM, Alan Meyer <ameyer2@yahoo.com> wrote: >> Python will copy something only when you tell it to copy. A simple way >> of copying a list is to slice it: >> >> someList = self._someList[:] > > And another simple way: > > ... > someList = list(self._someList) > ... I generally prefer the latter. It's clearer, and it guarantees that the result will be a list, which is usually what you want in these situations, rather than whatever unexpected type was passed in. Cheers, Ian
[toc] | [prev] | [next] | [standalone]
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2011-10-25 17:08 -0700 |
| Message-ID | <mailman.2219.1319587711.27778.python-list@python.org> |
| In reply to | #14979 |
On Tue, 25 Oct 2011 14:05:49 -0600, Ian Kelly <ian.g.kelly@gmail.com>
declaimed the following in gmane.comp.python.general:
> On Tue, Oct 25, 2011 at 1:50 PM, Alan Meyer <ameyer2@yahoo.com> wrote:
> >> Python will copy something only when you tell it to copy. A simple way
> >> of copying a list is to slice it:
> >>
> >> someList = self._someList[:]
> >
> > And another simple way:
> >
> > ...
> > someList = list(self._someList)
> > ...
>
> I generally prefer the latter. It's clearer, and it guarantees that
> the result will be a list, which is usually what you want in these
> situations, rather than whatever unexpected type was passed in.
>
Where's the line form to split those who'd prefer the first vs the
second result in this sample <G>:
>>> unExpected = "What about a string"
>>> firstToLast = unExpected[:]
>>> repr(firstToLast)
"'What about a string'"
>>> explicitList = list(unExpected)
>>> repr(explicitList)
"['W', 'h', 'a', 't', ' ', 'a', 'b', 'o', 'u', 't', ' ', 'a', ' ', 's',
't', 'r', 'i', 'n', 'g']"
>>>
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
[toc] | [prev] | [next] | [standalone]
| From | Mel <mwilson@the-wire.com> |
|---|---|
| Date | 2011-10-25 22:48 -0400 |
| Message-ID | <j87sdc$o8$1@speranza.aioe.org> |
| In reply to | #14988 |
Dennis Lee Bieber wrote:
> Where's the line form to split those who'd prefer the first vs the
> second result in this sample <G>:
>
>>>> unExpected = "What about a string"
>>>> firstToLast = unExpected[:]
>>>> repr(firstToLast)
> "'What about a string'"
>>>> explicitList = list(unExpected)
>>>> repr(explicitList)
> "['W', 'h', 'a', 't', ' ', 'a', 'b', 'o', 'u', 't', ' ', 'a', ' ', 's',
> 't', 'r', 'i', 'n', 'g']"
>>>>
Well, as things stand, there's a way to get whichever result you need. The
`list` constructor builds a single list from a single iterable. The list
literal enclosed by `[`, `]` makes a list containing a bunch of items.
Strings being iterable introduces a wrinkle, but `list('abcde')` doesn't
create `['abcde']` just as `list(1)` doesn't create `[1]`.
Mel.
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2011-10-25 18:30 -0600 |
| Message-ID | <mailman.2221.1319589064.27778.python-list@python.org> |
| In reply to | #14979 |
On Tue, Oct 25, 2011 at 6:08 PM, Dennis Lee Bieber <wlfraed@ix.netcom.com> wrote: > Where's the line form to split those who'd prefer the first vs the > second result in this sample <G>: > >>>> unExpected = "What about a string" >>>> firstToLast = unExpected[:] Strings are immutable. That doesn't suffice to copy them, even assuming you would want to do so in the first place. >>> unExpected is firstToLast True If you find yourself needing to make a copy, that usually means that you plan on modifying either the original or the copy, which in turn means that you need a type that supports modification operations, which usually means a list. If you pass in a string and then copy it with [:] and then try to modify it, you'll get an exception. If you don't try to modify it, then you probably didn't need to copy it in the first place. Cheers, Ian
[toc] | [prev] | [next] | [standalone]
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2011-10-22 17:55 -0700 |
| Message-ID | <mailman.2139.1319331340.27778.python-list@python.org> |
| In reply to | #14856 |
On Sat, 22 Oct 2011 17:26:22 -0700 (PDT), Gnarlodious
<gnarlodious@gmail.com> declaimed the following in
gmane.comp.python.general:
> Say this:
>
> class tester():
> _someList = [0, 1]
> def __call__(self):
> someList = self._someList
> someList += "X"
> return someList
>
> test = tester()
>
> But guess what, every call adds to the variable that I am trying to
> copy each time:
You never copied it... You just created a temporary local reference
to the same object
_someList = [0, 1]
creates a mutable list object containing two elements; it then binds the
/name/ "_someList" to that object.
someList = self._someList
finds the OBJECT to which "self._someList" is bound, and binds a second
name "someList" to the same object.
someList += "X"
retrieves the OBJECT to which "someList" is bound, mutates it by
appending an "X".
Nowhere do you ever create a NEW list object. Try
someList = self._someList[:]
which finds the object to which "self._someList" is bound, extracts a
sublist [:] (from first element to last element) -- this is a NEW list
-- and binds "someList" to that new object.
> Can someone explain this behavior? And how to prevent a classwide
> constant from ever getting changed?
"Ever"? Can't really be done with Python -- if you know it exists,
you can get to it and rebind it, or mutate it if it is a mutable object.
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web