__new__

Ethan Furman ethan at stoneleaf.us
Mon Aug 4 13:46:54 EDT 2008


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__?

~Ethan~



More information about the Python-list mailing list