__new__

Ethan Furman ethan at stoneleaf.us
Tue Aug 5 19:20:03 EDT 2008


Rhamphoryncus wrote:
> On Aug 4, 11:46 am, Ethan Furman <et... at stoneleaf.us> 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.

Thanks, Rhamphoryncus!




More information about the Python-list mailing list