473,574 Members | 3,101 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

modifying __new__ of list subclass

Hi,

I'm been trying to create some custom classes derived from some of
python's built-in types, like int and list, etc. I've run into some
trouble, which I could explain with a couple simple examples. Lets say
I want an int-derived class that is initilized to one greater than what
it's constructor is given:

class myint(int):
def __new__(cls, intIn):
newint = int(intIn+1)
return int.__new__(cls , newint)

print myint(3), myint(10)
Okay, seems to do what I want. Now, lets say I want a list class that
creates a list of strings, but appends "_" to each element. I try the
same thing:
class mylist(list):
def __new__(cls, listIn):
newlist = list()
for i in listIn:
newlist.append( str(i) + "_")
print "newlist: ", newlist
return list.__new__(cl s, newlist)

print mylist(("a","b" ,"c"))

Doesn't seem to work, but that print statement shows that the newlist is
what I want... Maybe what I return from __new__ is overwritten in
__init__? Could someone enlighten me as to why - and why this is
different than the int case?

Thanks,
Ken
Aug 15 '06 #1
5 2147
Ken Schutte wrote:
I want an int-derived class that is initilized to one greater than what
it's constructor is given:

class myint(int):
def __new__(cls, intIn):
newint = int(intIn+1)
return int.__new__(cls , newint)
Or simply:

class myint(int):
def __new__(cls, int_in):
return int.__new__(cls , int_in + 1)
Now, lets say I want a list class that
creates a list of strings, but appends "_" to each element. I try the
same thing:

class mylist(list):
def __new__(cls, listIn):
newlist = list()
for i in listIn:
newlist.append( str(i) + "_")
print "newlist: ", newlist
return list.__new__(cl s, newlist)
The __new__ method is for immutable types. So things like str and int
do their initialization in __new__. But for regular mutable types, you
should do your initialization in __init__::

class mylist(list):
def __init__(self, list_in):
for item in list_in:
self.append(str (item) + '_')

STeve
Aug 15 '06 #2
Steven Bethard wrote:
>
The __new__ method is for immutable types. So things like str and int
do their initialization in __new__. But for regular mutable types, you
should do your initialization in __init__::
I see... So, is there a use for __new__ in mutable types? From my
list-derirved class, it was obviously being called, but it's return
value is totally ignored?

Thanks for the reply.

Aug 15 '06 #3
Ken Schutte <ks******@csail .mit.eduwrote:
Steven Bethard wrote:

The __new__ method is for immutable types. So things like str and int
do their initialization in __new__. But for regular mutable types, you
should do your initialization in __init__::

I see... So, is there a use for __new__ in mutable types? From my
list-derirved class, it was obviously being called, but it's return
value is totally ignored?
Wrong: the return value of __new__ is most definitely NOT "totally
ignored", since it's what gets passed as the first argument of __init__
(as long as it's an instance of the type in question). Easy to check
for yourself, e.g.:
>>class ha(list):
.... def __new__(cls, *a):
.... x = list.__new__(cl s, *a)
.... x.foo = 23
.... return x
....
>>z = ha()
z.foo
23
>>>
as you can see, the "totally ignored" hypothesis is easily disproved.

Of course, there's no particular reason why class ha would _want_ to set
the .foo attribute in __new__ rather than __init__, so that doesn't yet
answer your other question about "is there a use". That answer is a
resounding "yes", but the uses may be subtler than you're considering:
for example, you may use the subtype as a general-purpose "factory", so
that instantiating the subtype may return objects that are not in fact
instances of the subtype (that bypasses the __init__ call); or, the
overriding of __new__ may go together with the overriding of __init__
(so that the latter doesn't blast the object's state) for such purposes
as singletons or more generally types with a finite "pool" of instances.
Alex

Aug 15 '06 #4
Ken Schutte wrote:
Steven Bethard wrote:
>>
The __new__ method is for immutable types. So things like str and int
do their initialization in __new__. But for regular mutable types,
you should do your initialization in __init__::

I see... So, is there a use for __new__ in mutable types? From my
list-derirved class, it was obviously being called, but it's return
value is totally ignored?
Not ignored, it's just having it's __init__ method called after your
__new__ method.

It might help for a moment to consider what happens when you call a
class object, e.g.::

c = C()

Just like any other object, when Python sees the ``()``, it looks for a
__call__ method on the object. Now classes are instances of the
``type`` type, which has a call method that looks something like::

def __call__(cls, *args, **kwargs):
result = cls.__new__(cls , *args, **kwargs)
if isinstance(resu lt, cls):
result.__init__ (*args, **kwargs)
return result

What's happening in your list case is that list.__init__ clears the list::
>>l = [1, 2, 3]
l.__init__( )
l
[]

So even though your __new__ method returns the object you want, the
__init__ method is clearing out all the items you've added and then
re-adding them as it normally would. To prove this to yourself, take a
look at what happens when we override __init__::
>>class mylist(list):
... def __new__(cls, items):
... result = super(mylist, cls).__new__(cl s)
... for item in items:
... result.append(' %s_' % item)
... return result
...
>>mylist([1, 2, 3])
[1, 2, 3]
>>class mylist(list):
... def __new__(cls, items):
... result = super(mylist, cls).__new__(cl s)
... for item in items:
... result.append(' %s_' % item)
... return result
... def __init__(self, items):
... pass
...
>>mylist([1, 2, 3])
['1_', '2_', '3_']

Of course, I've made __new__ work above, but the simpler solution is
just to override __init__ since that's where all the work's being done
anyway.

See Alex Martelli's response to answer your question "So, is there a use
for __new__ in mutable types?". You'd probably only want to override
__new__ if you were going to use the class as a factory to produce a
bunch of different types of objects.

STeVe
Aug 15 '06 #5
Steven Bethard wrote:
So even though your __new__ method returns the object you want, the
__init__ method is clearing out all the items you've added and then
re-adding them as it normally would. To prove this to yourself, take a
look at what happens when we override __init__::
Okay, I see what's happening now. Steve and Alex - thanks for the great
explanations.

Ken
Aug 15 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2300
by: Michele Simionato | last post by:
Let me show first how does it work for tuples: >>> class MyTuple(tuple): .... def __new__(cls,strng): # implicit conversion string of ints => tuple .... return super(MyTuple,cls).__new__(cls,map(int,strng.split())) >>> MyTuple('1 2') (1, 2) No wonder here, everything is fine. However, if I do the same for lists I get the...
3
2030
by: H Jansen | last post by:
I try to work out how to use __new__ and metaclass (or __metaclass__) mechanisms in order to change the base class at runtime. I haven't been successful so far, however, even after also reading most of the relevant documentation. The most simple representation (an oversimplification indeed) of what I'm trying to accomplish is this: class...
9
6198
by: Felix Wiemann | last post by:
Sometimes (but not always) the __new__ method of one of my classes returns an *existing* instance of the class. However, when it does that, the __init__ method of the existing instance is called nonetheless, so that the instance is initialized a second time. For example, please consider the following class (a singleton in this case): >>>...
5
2493
by: could ildg | last post by:
As there is already __init__, why need a __new__? What can __new__ give us while __init__ can't? In what situations we should use __new__? And in what situations we must use __new__? Can __new__ take the place of __init__? Thanks.
1
4989
by: s.lipnevich | last post by:
Hi All, Is anything wrong with the following code? class Superclass(object): def __new__(cls): # Questioning the statement below return super(Superclass, cls).__new__(Subclass) class Subclass(Superclass): pass
18
1695
by: Paulo da Silva | last post by:
Sorry to put here too many questions about __init__ __new__ stuff but I always found a new problem when using them. I have searched for simple __new__ docs on how to do the basic things but find none. After trying the solutions people gently posted here (thanks) I run into new trouble when I go with further development. Here is the new...
5
1447
by: Sandra-24 | last post by:
Ok here's the problem, I'm modifying a 3rd party library (boto) to have more specific exceptions. I want to change S3ResponseError into about 30 more specific errors. Preferably I want to do this by changing as little code as possible. I also want the new exceptions to be a subclass of the old S3ResponseError so as to not break old code that...
4
1786
by: Ethan Furman | last post by:
Emile van Sebille wrote: 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. ~Ethan~
3
1377
by: macaronikazoo | last post by:
i'm having a hell of a time getting this to work. basically I want to be able to instantiate an object using either a list, or a string, but the class inherits from list. if the class is instantiated with a string, then run a method over it to tokenize it in a meaningful way. so how come this doesn't work??? if I do this: a=TMP(...
0
7726
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8052
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8234
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7815
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
8098
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6452
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5620
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
1
1339
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1060
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.