On Aug 4, 11:46 am, Ethan Furman <[EMAIL PROTECTED]> wrote: > Mel wrote: > > Ethan Furman wrote: > > >>Emile van Sebille wrote: > > >>>Ethan Furman wrote: > > >>>> --> d25._int = (1, 5) > > >>>Python considers names that start with a leading underscore as internal > >>>or private, and that abuse is the burden of the abuser... > >>>Is bytecodehacks still around? That was serious abuse :) > > >>Good point. What I'm curious about, though, is the comment in the code > >>about making the Decimal instance immutable. I was unable to find docs > >>on that issue. > > > There's something in the Language Reference, chapter 3.1 'Objects, Values > > and Types'. > > > Mel. > > Thanks, Mel. > > I had actually read that once already, but your post caused me to reread > it, and evidently the ideas there had had enough time to percolate > through my mind. > > --> from decimal import Decimal > --> d25 = Decimal(25) > --> d25 > Decimal("25") > --> d25.testing = 'immutable' > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > AttributeError: 'Decimal' object has no attribute 'testing' > > Decimals are immutable in that we cannot add new attributes to them. > > The documentation in Language Reference 3.4.2.4 '__slots__' has this to say: > If defined in a new-style class, __slots__ reserves space for > the declared variables and prevents the automatic creation of > __dict__ and __weakref__ for each instance. > and > Without a __dict__ variable, instances cannot be assigned new > variables not listed in the __slots__ definition. Attempts to > assign to an unlisted variable name raises AttributeError. > > So the question I have now is this: is __new__ necessary, or would > __init__ have also worked? Let's see... > > class tester(object): > __slots__ = ['test1', 'test2', 'test3'] > def __init__(self, value1, value2, value3): > self.test1 = value1 > self.test2 = value2 > self.test3 = value3 > > --> import tester > --> testee = tester.tester(1, 2, 3) > --> testee > <tester.tester object at 0x009E7328> > --> dir(testee) > ['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', > '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', > '__repr__', '__setattr__', '__slots__', '__str__', 'test1', 'test2', > 'test3'] > --> testee.test4 = 4 > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > AttributeError: 'tester' object has no attribute 'test4' > > For this simple test, it looks like __init__ works just fine. So, > besides consistency (which is important) am I missing any other reasons > to use __new__ instead of __init__?
If you subclass a builtin immutable like int then you need to override __new__, as __init__ has no effect. Decimal is written in python, so this is irrelevant, but if there are plans to rewrite it in C (which I believe there are) then it'd need to use __new__ at that point. Using __new__ even in the python version then becomes a way to future-proof the API. -- http://mail.python.org/mailman/listinfo/python-list