Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

making a class return None from __init__

0 views
Skip to first unread message

Rajarshi Guha

unread,
Oct 4, 2002, 4:09:31 PM10/4/02
to
Hi,
I have a class which makes some basic error checks in the __init__
function. Ideally, if the parameters passed to the __init__ function fail
the checks I would like to return a None. But this does'nt seem to
happen:

class Graph:

def __init__(self,v):
if SOME_TEST:
return None

However when I test it out as:

g = Graph(v)
print g

(where v will fail) I always get <__main__.Graph instance at 0xXXXXXX>
Is there any way to make the constructor return a None object?

Thanks,

Max M

unread,
Oct 4, 2002, 4:46:11 PM10/4/02
to
Rajarshi Guha wrote:

> (where v will fail) I always get <__main__.Graph instance at 0xXXXXXX>
> Is there any way to make the constructor return a None object?


def noner():
return

print noner()

>>> None


regards Max M

The reason I don't reach any higher is that I stand on the shoulders of
little people.

Martin v. Loewis

unread,
Oct 4, 2002, 4:50:31 PM10/4/02
to
Rajarshi Guha <raja...@presidency.com> writes:

> Is there any way to make the constructor return a None object?

No. When __init__ is invoked, the object it "returns" is already
determined - it is the self object. You cannot change the identity of
this object, or the fact that it is an instance object, you can only
modify it.

Therefore, the return value of __init__ is irrelevant. Python checks
that applications do not attempt to "return" something from __init__:
If there is a non-None return value, Python raises an error.

If you want a constructor to fail, instead of completing, consider to
raise an exception. If you want Graph(foo) to return None, make Graph
a function:

class _Graph:

def __init__(self,v):
pass

def Graph(v):
if SOME_TEST:
return None
return _Graph(v)

If you absolutely must have a type whose constructor returns None,
implement a type that inherits from object, and implement an __new__.

HTH,
Martin

sism...@hebmex.com

unread,
Oct 4, 2002, 4:24:38 PM10/4/02
to
> From: Rajarshi Guha [mailto:raja...@presidency.com]

>
> Hi,
> I have a class which makes some basic error checks in the __init__
> function. Ideally, if the parameters passed to the __init__
> function fail
> the checks I would like to return a None. But this does'nt seem to
> happen:
>
> class Graph:
>
> def __init__(self,v):
> if SOME_TEST:
> return None
>
> However when I test it out as:
>
> g = Graph(v)
> print g
>
> (where v will fail) I always get <__main__.Graph instance at 0xXXXXXX>
> Is there any way to make the constructor return a None object?
>
> Thanks,
>

Hmmm... I believe you have a simple misunderstanding;
whatever value __init__() would return is irretrievably
lost (ok, enough drama), because __init__() is not called
to *create* the object, but to *initialize* it, the
object is already allocated by the time __init__() is
called.

What you *can* do is raise an exception, in which case
the assignment is aborted.

Good luck.

-gustavo


Erik Max Francis

unread,
Oct 4, 2002, 5:56:16 PM10/4/02
to
Rajarshi Guha wrote:

> I have a class which makes some basic error checks in the __init__
> function. Ideally, if the parameters passed to the __init__ function
> fail
> the checks I would like to return a None. But this does'nt seem to
> happen:

...


> (where v will fail) I always get <__main__.Graph instance at 0xXXXXXX>
> Is there any way to make the constructor return a None object?

The return value of constructors is not used for anything; besides, the
default return value of any function without an explicit return
statement is None in the first place.

The proper way to handle this case is to raise an exception from the
constructor if something goes wrong. If you so desired you could wrap
the creation of the object in a secondary function which catches the
error and returns None instead of it catches an error:

def protectedGraph(v):
try:
return Graph(v)
except SomeError:
return None

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, USA / 37 20 N 121 53 W / &tSftDotIotE
/ \ We'll have to make our own luck from now on.
\__/ Louis Wu
The laws list / http://www.alcyone.com/max/physics/laws/
Laws, rules, principles, effects, paradoxes, etc. in physics.

Chad Netzer

unread,
Oct 4, 2002, 5:16:52 PM10/4/02
to
On Friday 04 October 2002 13:46, Max M wrote:
> Rajarshi Guha wrote:
> > (where v will fail) I always get <__main__.Graph instance at
> > 0xXXXXXX> Is there any way to make the constructor return a None
> > object?
>
> def noner():
> return

ie. Create a factory function that returns the initialized class when
everything goes well, or None upon failure:

class MyClass:
def __init__( self, arg1, arg2, arg3 ):
return

def MyClassFactory( arg1, arg2, arg3 ):
if valid_args( arg1, arg2, arg3 )
return MyClass( arg1, arg2, arg3 )
else:
return None

Note - this is arguably bad style, UNLESS it is clear that you are
invoking a factory rather than a class constructor. Typically, you use
a factory to have flexibility in choosing which class is actually
instantiated, NOT because you need to test error conditions.

Better to use exceptions in the __init__, and abort the class
initialization if you cannot use the class. Returning either a class
or None, just doesn't feel right, especially if the user is assuming
only one specific class to be created.

--

Chad Netzer
cne...@mail.arc.nasa.gov

Aahz

unread,
Oct 4, 2002, 7:47:00 PM10/4/02
to
In article <3D9E0E80...@alcyone.com>,

Erik Max Francis <m...@alcyone.com> wrote:
>
>The proper way to handle this case is to raise an exception from the
>constructor if something goes wrong.

__init__() is *NOT* a constructor, it's an initializer. If you want a
constructor, inherit from object and use __new__().
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

Project Vote Smart: http://www.vote-smart.org/

Erik Max Francis

unread,
Oct 4, 2002, 8:16:47 PM10/4/02
to
Aahz wrote:

> In article <3D9E0E80...@alcyone.com>,
> Erik Max Francis <m...@alcyone.com> wrote:
>
> >The proper way to handle this case is to raise an exception from the
> >constructor if something goes wrong.
>
> __init__() is *NOT* a constructor, it's an initializer. If you want a
> constructor, inherit from object and use __new__().

It's a constructor in the same way that a C++ or Java constructor is
one; this is standard terminology. By the time the constructor gets
called, the object has already been created. Strictly speaking it's an
initializer. __new__ would be analogous to an overridden operator new
in C++, which is _not_ a constructor.

If you are trying to make a point that the role what is usually called a
"constructor" is really more along the lines of an initializer, the
point is well-taken, but I was using standard terminology in the
accepted way.

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, USA / 37 20 N 121 53 W / &tSftDotIotE

/ \ The people are to be taken in very small doses.
\__/ Ralph Waldo Emerson

Alex Martelli

unread,
Oct 5, 2002, 6:16:00 AM10/5/02
to
Erik Max Francis wrote:

> Rajarshi Guha wrote:
>
>> I have a class which makes some basic error checks in the __init__
>> function. Ideally, if the parameters passed to the __init__ function
>> fail
>> the checks I would like to return a None. But this does'nt seem to
>> happen:
> ...
>> (where v will fail) I always get <__main__.Graph instance at 0xXXXXXX>
>> Is there any way to make the constructor return a None object?
>
> The return value of constructors is not used for anything; besides, the

Hmmm, it's used to check that it's None and give an exception otherwise...:

[alex@lancelot ba]$ python
Python 2.3a0 (#1, Oct 4 2002, 13:05:05)
[GCC 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class X:
... def __init__(self):
... return 1
...
>>> x = X()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: __init__() should return None
>>>

That's probably what you mean, but I just thought I'd clarify it.

> default return value of any function without an explicit return
> statement is None in the first place.
>
> The proper way to handle this case is to raise an exception from the
> constructor if something goes wrong. If you so desired you could wrap
> the creation of the object in a secondary function which catches the
> error and returns None instead of it catches an error:
>
> def protectedGraph(v):
> try:
> return Graph(v)
> except SomeError:
> return None

Yes to all of this -- a factory function of some kind or another is
the best approach when you're not sure what type of object you want
to generate (and None is a different type from Graph, so this is
a case in point:-). In modern Python you can dress up such a
function as a class's static method __new__, but keeping it as a
separate function is often preferable anyway -- clearer, simpler,
more portable to older Python versions (e.g., the current release
of Jython, which still implements the Python 2.1 language).


Alex

0 new messages