Re: Immutability and Python

Discussion in 'Python' started by Paul Rubin, Oct 29, 2012.

  1. Paul Rubin

    Paul Rubin Guest

    andrea crotti <> 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.
     
    Paul Rubin, Oct 29, 2012
    #1
    1. Advertising

  2. 2012/10/29 Paul Rubin <>:
    > andrea crotti <> 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..
     
    andrea crotti, Oct 29, 2012
    #2
    1. Advertising

  3. 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


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.14 (GNU/Linux)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

    iQEcBAEBAgAGBQJQjsPoAAoJEAOzoR8eZTzgo2cH/jgg+Ht3FtDrAlswAV9P/pgo
    nHahvG/FwLkrAwvJB/YE15SMv31XdrALu3BYqfzeOJOTmKZx/QUy8/HeMzOIqJak
    /hwrvGOqDh+12CAhBI3jWiTup9jdROPkLonx31EmKy5EWgqKjTuSEbBZeKqXpxyX
    SjHjXlGDup20FRYb+gTmsJfDqmyctq++JL9yfaBytgh/LzRhHPjaY/keRDo4f8S1
    GRT00H7xrkGsmxpRrUG0T4sbRX1CQ2FtmHb7lrmR+gpDt2F5iw6Cknx0Su5z6oFV
    gx2tzDhJ0JbpjxQcukT68IUrCBPeSBRecxpZGoNPNoIIFLjnYIIKrsCrKroz7pY=
    =QnP7
    -----END PGP SIGNATURE-----
     
    Evan Driscoll, Oct 29, 2012
    #3
  4. Paul Rubin

    Terry Reedy Guest

    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
     
    Terry Reedy, Oct 29, 2012
    #4
  5. On Mon, Oct 29, 2012 at 12:46 PM, Paul Rubin <> wrote:
    > andrea crotti <> 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
     
    Devin Jeanpierre, Oct 29, 2012
    #5
  6. 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
     
    Steven D'Aprano, Oct 29, 2012
    #6
  7. Paul Rubin

    Chris Kaynor Guest

    On Mon, Oct 29, 2012 at 3:30 PM, Steven D'Aprano
    <> 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'
     
    Chris Kaynor, Oct 29, 2012
    #7
  8. On Mon, 29 Oct 2012 15:45:59 -0700, Chris Kaynor wrote:

    > On Mon, Oct 29, 2012 at 3:30 PM, Steven D'Aprano
    > <> 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
     
    Steven D'Aprano, Oct 29, 2012
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. andrea crotti

    Immutability and Python

    andrea crotti, Oct 29, 2012, in forum: Python
    Replies:
    8
    Views:
    227
    Thomas Rachel
    Nov 8, 2012
  2. andrea crotti

    Re: Immutability and Python

    andrea crotti, Oct 29, 2012, in forum: Python
    Replies:
    0
    Views:
    181
    andrea crotti
    Oct 29, 2012
  3. andrea crotti

    Re: Immutability and Python

    andrea crotti, Oct 29, 2012, in forum: Python
    Replies:
    0
    Views:
    178
    andrea crotti
    Oct 29, 2012
  4. Mark Lawrence

    Re: Immutability and Python

    Mark Lawrence, Oct 29, 2012, in forum: Python
    Replies:
    0
    Views:
    188
    Mark Lawrence
    Oct 29, 2012
  5. Terry Reedy

    Re: Immutability and Python

    Terry Reedy, Oct 29, 2012, in forum: Python
    Replies:
    0
    Views:
    177
    Terry Reedy
    Oct 29, 2012
Loading...

Share This Page