Class instantiation question

Alex Martelli aleax at aleax.it
Wed Oct 8 10:35:20 EDT 2003


Todd Johnson wrote:

> Ok, say I have a class MyClass and an __init__(self,
> a, b)  Say that a and b are required to be integers
> for example. So my init looks like:
> 
> __init__(self, a, b):
>     try:
>         self.one = int(a)
>         self.two = int(b)
>     except ValueError:
>         #nice error message here
>         return None

Any return statement in __init__ MUST return None (you
get an error otherwise).  The job of __init__ is
preparing the self, which is already created.

> I have even tried a similar example with if-else
> instead of try-except, but no matter what if I call
> 
> thisInstance = MyClass(3, "somestring")
> 
> it will set self.one to 3 and self.two will be
> uninitialised. The behavior I am hoping for, is that
> thisInstance is not created instead(or is None). How
> do I get the behavior I am looking for?

It's not a nice architecture AT ALL, but if you
insist you can have it -- as long at least as
class MyClass is new-style, e.g., subclasses
object -- by defining a __new__ method.  The
process of calling a class can be summarized as:

[[ function equivalent to calling theclass with
   positional args *a and named args **k ...: ]]

    result = theclass.__new__(theclass, *a, **k)
    if isinstance(result, theclass):
        theclass.__init__(result, *a, **k)
    return result

Normally, it's best to do all the work in __init__
and thus to inherit __new__ from type object.
But that's only for the NORMAL case, where one
assumes that calling theclass always either
raises / propagates an exception OR else returns
an instance of theclass.  Since you deliberately
want to break this normal, expected rule --
having the call to theclass return None instead! --
you would need to define __new__.

For example:


class theclass(object):

   def __new__(cls, a, b):
     self = object.__new__(cls)
     try:
         self.one = int(a)
         self.two = int(b)
     except ValueError:
         #nice error message here
         return None
     else:
         return self

I would still recommend you to reconsider the
architecture you want.  Why MUST you break all
normal Pythonic expectations of users of your
class...?  If you must, Python lets you -- but
MUST you, really...?


Alex







More information about the Python-list mailing list