Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #32391 > unrolled thread

Re: Immutability and Python

Started byandrea crotti <andrea.crotti.0@gmail.com>
First post2012-10-29 16:12 +0000
Last post2012-10-29 14:25 -0400
Articles 9 — 7 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Immutability and Python andrea crotti <andrea.crotti.0@gmail.com> - 2012-10-29 16:12 +0000
    Re: Immutability and Python Paul Rubin <no.email@nospam.invalid> - 2012-10-29 09:46 -0700
      Re: Immutability and Python andrea crotti <andrea.crotti.0@gmail.com> - 2012-10-29 17:05 +0000
        Re: Immutability and Python Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-10-29 22:30 +0000
          Re: Immutability and Python Chris Kaynor <ckaynor@zindagigames.com> - 2012-10-29 15:45 -0700
            Re: Immutability and Python Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-10-29 23:14 +0000
      Re: Re: Immutability and Python Evan Driscoll <driscoll@cs.wisc.edu> - 2012-10-29 12:58 -0500
      Re: Immutability and Python Terry Reedy <tjreedy@udel.edu> - 2012-10-29 14:03 -0400
      Re: Immutability and Python Devin Jeanpierre <jeanpierreda@gmail.com> - 2012-10-29 14:25 -0400

#32391 — Re: Immutability and Python

Fromandrea crotti <andrea.crotti.0@gmail.com>
Date2012-10-29 16:12 +0000
SubjectRe: Immutability and Python
Message-ID<mailman.3025.1351527152.27098.python-list@python.org>
2012/10/29 Jean-Michel Pichavant <jeanmichel@sequans.com>:
>
>
> In an OOP language num.increment() is expected to modify the object in place.
> So I think you're right when you say that functional languages technics do not necessarily apply to Python, because they don't.
>
> I would add that what you're trying to suggest in the first post was not really about immutability, immutable objects in python are ... well immutable, they can be used as a dict key for instance, your NumWrapper object cannot.
>
>
> JM

Yes right immutable was not the right word, I meant that as a contract
with myself I'm never going to modify its state.

Also because how doi I make an immutable object in pure Python?

But the example with the dictionary is not correct though, because this:

In [145]: class C(object):
   .....:     def __hash__(self):
   .....:         return 42
   .....:

In [146]: d = {C(): 1}

works perfectly, but an object of class C can mutate as much as it
wants, as my NumWrapper instance..

[toc] | [next] | [standalone]


#32397

FromPaul Rubin <no.email@nospam.invalid>
Date2012-10-29 09:46 -0700
Message-ID<7x625t6xaj.fsf@ruckus.brouhaha.com>
In reply to#32391
andrea crotti <andrea.crotti.0@gmail.com> writes:
> Also because how doi I make an immutable object in pure Python?

Numbers in Python are already immutable.  What you're really looking for
is a programming style where you don't bind any variable more than once.

This gives rise to a programming style that Python can support to a
certain extent, but for which some other languages are designed from the
beginning.

You might look at http://learnyouahaskell.com (online book) if you want
to try the above approach.

[toc] | [prev] | [next] | [standalone]


#32403

Fromandrea crotti <andrea.crotti.0@gmail.com>
Date2012-10-29 17:05 +0000
Message-ID<mailman.3031.1351530311.27098.python-list@python.org>
In reply to#32397
2012/10/29 Paul Rubin <no.email@nospam.invalid>:
> andrea crotti <andrea.crotti.0@gmail.com> writes:
>> Also because how doi I make an immutable object in pure Python?
>
> Numbers in Python are already immutable.  What you're really looking for
> is a programming style where you don't bind any variable more than once.
>
> This gives rise to a programming style that Python can support to a
> certain extent, but for which some other languages are designed from the
> beginning.
>
> You might look at http://learnyouahaskell.com (online book) if you want
> to try the above approach.
> --
> http://mail.python.org/mailman/listinfo/python-list


I meant how do I create new immutables classes myself, I guess that's
possible writing C extensions but I don't see in pure Python..

Anyway I know haskell already, and that's one of the reasons why I was
trying to evaluate if the same techniques could be useful in Python as
well..

[toc] | [prev] | [next] | [standalone]


#32430

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-10-29 22:30 +0000
Message-ID<508f0390$0$29967$c3e8da3$5496439d@news.astraweb.com>
In reply to#32403
On Mon, 29 Oct 2012 17:05:07 +0000, andrea crotti wrote:

> I meant how do I create new immutables classes myself, I guess that's
> possible writing C extensions but I don't see in pure Python..

Well, you can't *quite* make a truly immutable class in pure-Python, 
because if *your* Python code can manipulate the class during 
construction then so can the caller's Python code after construction.

The trivial way to make an immutable class in Python is to inherit from 
an already immutable class and add behaviour but no state:

class MyInt(int):
    def inc(self):
        return self.__class__(self + 1)


Otherwise, you can add private state and rely on the caller not shooting 
themselves in the foot by accessing single-underscore names, use 
properties to protect private state, etc.

See the source code for collections.namedtuple and decimal.Decimal for 
some examples.

Warning: namedtuple is special, because it uses some runtime exec magic; 
most immutable classes do not need that. And Decimal is seriously large 
and complicated. But you can get some ideas from them both.

Also, see this:

http://northernplanets.blogspot.com.au/2007/01/immutable-instances-in-python.html



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#32433

FromChris Kaynor <ckaynor@zindagigames.com>
Date2012-10-29 15:45 -0700
Message-ID<mailman.3052.1351550783.27098.python-list@python.org>
In reply to#32430
On Mon, Oct 29, 2012 at 3:30 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Mon, 29 Oct 2012 17:05:07 +0000, andrea crotti wrote:
>
>> I meant how do I create new immutables classes myself, I guess that's
>> possible writing C extensions but I don't see in pure Python..
>
> Well, you can't *quite* make a truly immutable class in pure-Python,
> because if *your* Python code can manipulate the class during
> construction then so can the caller's Python code after construction.
>
> The trivial way to make an immutable class in Python is to inherit from
> an already immutable class and add behaviour but no state:
>
> class MyInt(int):
>     def inc(self):
>         return self.__class__(self + 1)
>
>
> Otherwise, you can add private state and rely on the caller not shooting
> themselves in the foot by accessing single-underscore names, use
> properties to protect private state, etc.
>

You'd also need to add __slots__ = () to the class definition to make
it immutable. Otherwise they still can shoot themselves in the foot by
adding new attributes.

>>> class MyInt(int):
...    def inc(self):
...            return self.__class__(self+1)
...
>>> a = MyInt()
>>> a.b = 1 # Oops. Mutated "a".
>>> a.b
1



>>> class MyInt(int):
...     __slots__ = ()
...     def inc(self):
...             return self.__class__(self + 1)
...
>>> a = MyInt()
>>> a.b = 1
AttributeError: 'MyInt' object has no attribute 'b'
Traceback (most recent call last):
  File "<stdin-inspect>", line 1, in <module>
AttributeError: 'MyInt' object has no attribute 'b'

[toc] | [prev] | [next] | [standalone]


#32441

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-10-29 23:14 +0000
Message-ID<508f0dea$0$29967$c3e8da3$5496439d@news.astraweb.com>
In reply to#32433
On Mon, 29 Oct 2012 15:45:59 -0700, Chris Kaynor wrote:

> On Mon, Oct 29, 2012 at 3:30 PM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> On Mon, 29 Oct 2012 17:05:07 +0000, andrea crotti wrote:
>>
>>> I meant how do I create new immutables classes myself, I guess that's
>>> possible writing C extensions but I don't see in pure Python..
>>
>> Well, you can't *quite* make a truly immutable class in pure-Python,
>> because if *your* Python code can manipulate the class during
>> construction then so can the caller's Python code after construction.
>>
>> The trivial way to make an immutable class in Python is to inherit from
>> an already immutable class and add behaviour but no state:
>>
>> class MyInt(int):
>>     def inc(self):
>>         return self.__class__(self + 1)
>>
>>
>> Otherwise, you can add private state and rely on the caller not
>> shooting themselves in the foot by accessing single-underscore names,
>> use properties to protect private state, etc.
>>
>>
> You'd also need to add __slots__ = () to the class definition to make it
> immutable. Otherwise they still can shoot themselves in the foot by
> adding new attributes.

"Doctor, it hurts when I do this."

"Then don't do that."


I'm not a big fan of preventatively using __slots__ merely to prevent the 
caller from tagging an object with extra data. Why do you care if the 
caller sticks a postit note on the object? It doesn't hurt the object, 
and if the caller loses track of which object has a postit note, that's 
their responsibility, not yours.

I often wish I could sick an attribute on built-ins, e.g. after 
calculating some numeric result as a float, stick an error estimate on 
it. Callers who care about the error estimate can inspect it; those who 
don't, will never even notice it.

If you have a good reason for using __slots__, then go right ahead. 
Otherwise, don't be paternalistic. This is Python, we have the right to 
shoot ourselves in the foot if we like.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#32410

FromEvan Driscoll <driscoll@cs.wisc.edu>
Date2012-10-29 12:58 -0500
Message-ID<mailman.3038.1351533554.27098.python-list@python.org>
In reply to#32397

[Multipart message — attachments visible in raw view] — view raw

On 10/29/2012 12:05 PM, andrea crotti wrote:
> I meant how do I create new immutables classes myself, I guess that's
> possible writing C extensions but I don't see in pure Python..

The short answer is: you don't, not really, except by using NamedTuple
if that gives you what you want.

The longer answer:

You can kinda get it somewhat if you define your own
__getattribute__/__setattribute__ functions. __setattribute__ of course
should never do anything except raise an error (one way or another
you'll need to make an exception for your __init__ function of course).
__getattribute__ should make sure no mutable references are returned:
e.g. you'll probably want to make it so someone can't side-step your
setter by saying someobject.__dict__["foo"] = "bar". (I return a copy of
the dict.) It will still be possible to bypass these protections though.

To really get true immutability in pure Python, you'll have to inherit
from tuple or NamedTuple (which inherits from tuple, I think). You can
see some discussion on Stack Overflow and some other places about this;
having played around with this a bit, I think it's not worth the hassle
and have done the __getattribute__/__setattribute__ thing the couple of
times I wanted immutability.

Evan

[toc] | [prev] | [next] | [standalone]


#32412

FromTerry Reedy <tjreedy@udel.edu>
Date2012-10-29 14:03 -0400
Message-ID<mailman.3039.1351533862.27098.python-list@python.org>
In reply to#32397
On 10/29/2012 1:05 PM, andrea crotti wrote:

> I meant how do I create new immutables classes myself, I guess that's
> possible writing C extensions but I don't see in pure Python..

If you mean class with immutable instances, mutate new instances in 
__new__ instead of __init__ and write a custom .__setattr__ that 
prevents changes thereafter.

If you want the class itself to be immutable (after creation), write a 
custom metaclass.

You may also need to think about .__getattribute__, but I never studied 
the detail completely and have forgotten what I learned.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#32415

FromDevin Jeanpierre <jeanpierreda@gmail.com>
Date2012-10-29 14:25 -0400
Message-ID<mailman.3041.1351535200.27098.python-list@python.org>
In reply to#32397
On Mon, Oct 29, 2012 at 12:46 PM, Paul Rubin <no.email@nospam.invalid> wrote:
> andrea crotti <andrea.crotti.0@gmail.com> writes:
>> Also because how doi I make an immutable object in pure Python?
>
> Numbers in Python are already immutable.  What you're really looking for
> is a programming style where you don't bind any variable more than once.

No, they were looking for a way to create classes whose instances are immutable.

Also, immutability has nothing to do with the presence or lack of for loops.

-- Devin

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web