On 4 Mar 2006 10:14:56 -0800 [EMAIL PROTECTED] 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__(cls, 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(ImmutableSet, 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 NotImplementedError, 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 ([EMAIL PROTECTED]) Anansi Spaceworks http://www.AnansiSpaceworks.com -- http://mail.python.org/mailman/listinfo/python-list