alphanumeric
alphanumeric

Reputation: 19359

How to return None while declaring Class instance

MyClass which is defined below accepts a single argument arg.

class MyClass(object):
    def __init__(self, arg):
        super(MyClass, self).__init__()
        if not isinstance(arg, int):
            return None
        else:
            self.arg = arg

If the incoming argument arg is not an integer I would like to return None instead of the instance of MyClass.

a = MyClass(arg='Text Argument')

But even while MyClass constructor __init__ returns None when the arg is not an integer the resulting variable a is still an instance of MyClass:

print a
<__main__.MyClass object at 0x0000000001FDEFD0>

How to make sure the variable a remains None if MyClass is given a non-integer argument?

Upvotes: 2

Views: 1090

Answers (2)

Moses Koledoye
Moses Koledoye

Reputation: 78564

You generally should not be doing this, but you could if you want to, by overriding your __new__, where the new instance is created:

class MyClass(object):
    def __new__(cls, **kwargs):
        if not isinstance(kwargs['arg'], int):
            return None
        return super(MyClass, cls).__new__(cls, **kwargs)

    def __init__(self, arg):
        super(MyClass, self).__init__()
        self.arg = arg

The __init__ method does not create the instance, it only initializes it, returning None from it is what is expected.

In the case __new__ returns an object that is not an instance (like None in this case), __init__ will not be called.

One of the reasons why you should not use the above is the following:

print isinstance(MyClass(arg='666'), MyClass) #-> False
# waaah!

A lot of things will start to break in your code, and the above is only just one example.

Upvotes: 2

deceze
deceze

Reputation: 522500

You should not return None from a constructor, even if it was possible. The result of MyClass() should always be an instance of MyClass or a compatible class; anything else would be Very Surprising And Error Inducing Behaviour™.

You could do this with a custom __new__ method, which creates the actual instance. But again, I would not recommend it.

You should be raising an exception if the object cannot be constructed with the given data:

class MyClass(object):
    def __init__(self, arg):
        super(MyClass, self).__init__()
        if not isinstance(arg, int):
            raise TypeError('arg must be an int')

        ...

Upvotes: 5

Related Questions