473,804 Members | 2,711 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Easy immutability in python?

Is there an *easy* way to make an object immutable in
python? Or perhaps I should say "one obvious way to do it"?
Oughtn't there to be one?

I've found a thread on how to do this[1], which essentially
says something like "redefine __setattr__, __delattr__,
__hash__, __eq__, __setitem__, delitem__ ... and probably
some other stuff too".

[1]

Yet, what you have to do is pretty mechanical (e.g. all the
mutators have to raise NotImplementedE rror and the hashes
and comparisons seem like they have obvious defaults).

Given that I have some kind of container, like an overloaded
list, and I just say "oh, I need that to be immutable, like
a tuple" -- it would be nice to just be able to declare it
so. I just want this for QA purposes -- I have a pretty
complex system, and I want the programmer to be warned when
he accidentally tries to change an immutable enumeration or
redefine a symbol.

I know a (hard and error-prone) way to do it, but I'm
thinking there must be a "smart" way to do it.

Is there some way to do that with, e.g. decorators?

(I haven't really figured out why I should want decorators,
is this a use case?).

Or maybe I should make an "Immutable" class, and just
inherit from it last so it overloads everything else with
the null interfaces?

--
Terry Hancock (ha*****@Anansi Spaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Mar 4 '06 #1
3 6379
Since this is a container that needs to be "immutable, like a tuple",
why not just inherit from tuple? You'll need to override the __new__
method, rather than the __init__, since tuples are immutable:

class a(tuple):
def __new__(cls, t):
return tuple.__new__(c ls, t)

cheers,
Jess

Mar 4 '06 #2
To be clear, in this simple example I gave you don't have to override
anything. However, if you want to process the values you place in the
container in some way before turning on immutability (which I assume
you must want to do because otherwise why not just use a tuple to begin
with?), then that processing should take place in a.__new__.

cheers,
Jess

Mar 4 '06 #3
On 4 Mar 2006 10:14:56 -0800
je*********@gma il.com wrote:
Since this is a container that needs to be "immutable,
like a tuple", why not just inherit from tuple? You'll
need to override the __new__ method, rather than the
__init__, since tuples are immutable:

class a(tuple):
def __new__(cls, t):
return tuple.__new__(c ls, t)


The reason this is undesireable, is because in the typical
use-case, I want to have TWO kinds of objects, one mutable,
and one immutable. Just like tuple / list. I would prefer
not to have to implement them completely separately. So
far, it's usually simpler to implement the mutable type
first -- the need for immutability semantics usually arises
after you have a mutable version.

But undoing mutability apparently is like making a sieve
watertight -- it would've been easier to design a ladle and
then put holes in it, than to design a sieve and then stop
up the holes.

In fact, my particular case wants to subclass Set and
ImmutableSet -- their contents, though, are also immutables
in principle. In fact the elements are similar to "int" or
"str", but I don't want to subclass those, because I don't
want them to have math methods or string methods.

I've considered several different approaches to this. One is
to create a "BaseVocabulary " as an abstract class, from
which the mutable and immutable types are drawn, and then
mix it in with Set and ImmutableSet:

class BaseVocabulary( object):
def __init__(self, values):
self._data = values
# (or something like that)
# other functionality

class Vocabulary(Set, BaseVocabulary) :
# stuff appropriate for the "open" vocabulary
pass

class Enumeration(Imm utableSet, BaseVocabulary) :
# stuff appropriate for the "closed" enumeration
pass

This is bad, both aesthetically and practically.
Aesthetically, because "abstract classes stink of Java" and
pragmatically because the __init__ from BaseVocabulary
will generally not work for the immutable case.

So I either have to rewrite it special, or go back in
time and fix the original, knowing that I'm going to want
an immutable variant.

Again with the aesthetics, it's just ugly that I can't
mutate an object in its __init__ and then make it immutable
after I'm done setting it up. The approach with __new__ and
using the superclass's __setattr__ to set values is nasty
boilerplate-rich cruft which forces me to go back and
completely re-implement the same functionality in a
completely different way, just because of something that
seems like a simple conceptual change (i.e. "don't overwrite
or extend this thing -- make a new one if you need a
change").

I even tried defining __setattr__ at the end of the
__init__, but that doesn't seem to work (or I'm doing it
wrongly).

Right now I'm leaning towards making a class "Immutable"
with all the mutator methods raising NotImplementedE rror,
and then subclass from this so that it overrides the
necessary methods. It's still going to mess with me, though,
because it will not allow the __init__ to work as planned,
and I'll have to go back and redesign the base class to work
with or without immutability.

Alternatively, I could just decide to change my practice and
implement ALL objects on the assumption that they will be
immutable, and add *mutability* after-the-fact. But that
seems like extraordinarily bad practice, since mutability is
usually the better default.

I'm going to dig through the sets module code to see how it
does this, but what little I've seen gives me a bad feeling
that this simple idea is hard to implement simply in Python
-- and that strikes me as a "wart", yes.

So, I'm wondering if there is a simple way after all.

1) Is there an idiom for this that I just don't know?

2) Have recent changes to the language made it easier?
(__new__ for example, is apparently new, or at least
newly documented -- but as I say, I'm not sure it's
the most practical solution for this problem).

3) Is there a "remarkably clever" way that I can tack
on, even if it isn't exactly simple?

and only in the unlikely event that answers 1-3 are all
"no", would I ask:

4) And as a last resort, if it really is hard, why?
Shouldn't a simple idea to express in English be easy to
express in Python? If it's really impossibly difficult,
maybe Python should provide a means to implement it.

Cheers,
Terry

--
Terry Hancock (ha*****@Anansi Spaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Mar 4 '06 #4

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

Similar topics

2
3662
by: javac | last post by:
for better or worse, my free time is consumed by two Java series books from Sun: Java Platform Performance, 2000, by Wilson and Kesselman Effective Java, 2001, by Bloch 1.) opinions on these books? good/bad/mediocre/great/etc? are they up to date, or out of date? 2.) please do check out my code at
4
1544
by: rb | last post by:
Hi This is a sample code I am working on. string a = "rb" string b = a Console.WriteLine(Object.ReferenceEquals(a,b)) In the above code, its printing true. I have a doubt on this output. When I say b = a, the system will create a new string called b and copy the value in a to b. Hence b and a should point to two new memory locations. Hence the output should be false, right
37
1869
by: Nick Maclaren | last post by:
The way that I read it, Python allows only values (and hence types) to be immutable, and not class members. The nearest approach to the latter is to use the name hiding conventions. Is that correct? Regards, Nick Maclaren.
0
1870
by: Tommy | last post by:
Our application uses BigDecimal, and BigDecimal is immutable. Immutability is certainly a good thing, but it also means that there are a lot more memory allocations (and collections). That's ok, we are all happy that Strings are immutable, but Java also gives us StringBuilder and StringBuffer. Is there anything similar for BigDecimal? BigDecimal operations are the hotspots in our application and the GC is also very busy collecting all...
0
772
by: Roy Smith | last post by:
In article <mailman.2119.1219612653.922.python-list@python.org>, "Hendrik van Rooyen" <mail@microcorp.co.zawrote: Reminds me of that great old song from "Saturday Night Hacker": Oh, oh, oh, oh. Flaying alive, flaying alive. Oh, oh, oh, oh. Flaying ali-i-i-i-i-ive!
0
165
by: Simon Brunning | last post by:
2008/8/25 Hendrik van Rooyen <mail@microcorp.co.za>: You can indeed use ctypes to modify the value of a string - see <http://tinyurl.com/5hcnwl>. You can use it to crash the OS, too. My advice - don't. -- Cheers, Simon B.
0
1233
by: Hendrik van Rooyen | last post by:
"Gabriel Genellina": Thanks Gabriel – looks like I really have to spend more time with that excellent document. Patrick Maupin:
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
9571
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10318
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
10069
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
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
5505
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...
0
5639
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4277
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

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.