Python __init__ return failure to create

Philip Massey picture Philip Massey · Jun 27, 2013 · Viewed 16.1k times · Source

First off, I know that the __init__() function of a class in Python cannot return a value, so sadly this option is unavailable.

Due to the structure of my code, it makes sense to have data assertions (and prompts for the user to give information) inside the __init__ function of the class. However, this means that the creation of the object can fail, and I would like to be able to gracefully recover from this.

I was wondering what the best way to continue with this is. I've considered setting a global boolean as a 'valid construction' flag, but I'd prefer not to.

Any other ideas (besides restructuring so assertions can happen outside of the initialization and values are passed in as arguments)? I'm basically looking for a way to have return 0 on success and return -1 on failure during initialization. (Like most C system calls)

Answer

jsbueno picture jsbueno · Jun 27, 2013

You could raise an exception when either assertio fail, or -, if you really don't want or can't work with exceptions, you can write the __new__ method in your classes - in Python, __init__ is technically an "initializer" method - and it should fill in he attributes and acquire some of the resources and others your object will need during its life cycle - However, Python does define a real constructor, the __new__ method, which is called prior to __init__- and unlike this, __new__ actually does return a value: the newly created (uninitialized) instance itself.

So you can place your checks inside __new__ and and simply return None is something fails - otherwise, return the result of the call to the superclass __new__ method (one can't do the actual memory allocation for the object in pure Python, so ultimately you have to call a constructor written in native code in a superclass - usually this is object.__new__ in the base of your class hierarchy.

NB: In Python 2, you must have object as the base class for your hierarchy - otherwise not only __new__ is not called, as a whole lot of features added later to Python objects will just not work. In short, class MyClass(object): , never class MyClass: - unless you are on Python3.