Can __init__ not return an object?

Steve Holden steve at holdenweb.com
Mon Apr 23 10:12:00 EDT 2007


Steven W. Orr wrote:
> On Sunday, Apr 22nd 2007 at 21:01 -0400, quoth Steve Holden:
[let's keep it on the list so everything gets indexed]
> =>Steven W. Orr wrote:
> =>> When I go to create an object I want to be able to decide whether the 
> =>> object is valid or not in __init__, and if not, I want the constructor to 
> =>> return something other than an object, (like maybe None). I seem to be 
> =>> having problems. At the end of __init__ I say (something like)
> =>> 
> =>>  	if self.something < minvalue:
> =>>  	    del self
> =>>  	    return None
> =>> 
> =>> and it doesn't work. I first tried just the return None, then I got crafty 
> =>> and tried the del self. Is what I'm trying to do possible in the 
> =>> constructor or do I have to check after I return? Or would raising an 
> =>> exception in the constructor be appropriate?
> =>> 
> =>> Am I even being clear?
> =>> 
> =>The trouble you have is that it's too late by the time you get to 
> =>__init__. The object has been created. The reason that "del self" 
> =>doesn't work is that all it does is remove the local name "self" from 
> =>the namespace of the method - you will find that if __init__ returns 
> =>anything *except* None you get an exception.
> =>
> =>Don't think of __init__ as a constructor - that's __new__, which *is* 
> =>expected to return a newly-created instance.
> =>
> =>Raising an exception in __init__ is perfectly permissible, but adopting 
> =>the new-style classes (inheriting from object) might give you a more 
> =>efficient solution to your problem.
> 
> Thanks Steve. I'm new but I do now understand that __init_ is an 
> initializer and that new is a constructor. I don't understand your last 
> sentence about new-style classes inheriting from an object. The object is 
> question is mine and doesn't inherit from anything. Can you explain what 
> you mean?
> 
Not "an object" but "object", the root of all Python types.

If you are very new you may not appreciate that Python currently 
implements two different class declaration mechanisms. The original 
classes, often now called "classic classes", couldn't be used to 
subclass Python's built-in types because they formed an independent and 
parallel class hierarchy. Among other things the instances don't have an 
accessible __new__ method:

  >>> class X: pass
  ...
  >>> type(X)
<type 'classobj'>
  >>>

At present the so-called "new-style" classes must specifically inherit 
from object (or, more correctly, must have a metaclass that is 
conformant with the protocol implemented by the type type, but the 
easiest way to do this is just to subclass object or one of the other 
built-in types):

  >>> class X(object): pass
  ...
  >>> type(X)
<type 'type'>
  >>>

So, all I was saying is that you might prefer to implement your solution 
as a new-style class, since that gives you access to your class's 
instance creation mechanism through the __new__ method. __new__ doesn't 
*have* to return an instance of the class whose __new__ method is 
called, and this might allow you to return exactly what your application 
needs without having to handle exceptions at the application code level.

regards
  Steve
-- 
Steve Holden       +1 571 484 6266   +1 800 494 3119
Holden Web LLC/Ltd          http://www.holdenweb.com
Skype: holdenweb     http://del.icio.us/steve.holden
Recent Ramblings       http://holdenweb.blogspot.co



More information about the Python-list mailing list