__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