Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent object from being created in Python constructor

How des one properly reject the creation of an object in a Python constructor? Consider an object:

class Triangle:
    def __init__(self, a, b, c):
        sides = [a, b, c]
        sides.sort()
        if sides[0]+sides[1] < sides[2]:
            return None
        self._a = a
        self._b = b
        self._c = c

If the sides are not logical for a triangle, I would like to reject the creation of a Triangle object. Returning None does not prevent the creation of the Triangle object, and returning False throws an exception. What is the proper way to handle this? Should I throw some type of exception when the wrong parameters are given?

like image 324
dotancohen Avatar asked Dec 27 '22 01:12

dotancohen


2 Answers

Either raise an exception

class Triangle:
    def __init__(self, a, b, c):
        sides = [a, b, c]
        sides.sort()
        if sides[0]+sides[1] < sides[2]:
            raise ValueError('invalid triangle!')
        self._a = a
        self._b = b
        self._c = c

or use an assert (which raises an exception itself)

class Triangle:
    def __init__(self, a, b, c):
        sides = [a, b, c]
        sides.sort()
        assert sides[0]+sides[1] >= sides[2]
        self._a = a
        self._b = b
        self._c = c

Which one is more appropriate depends on if throwing on invalid values is supposed to be part of your API (first version), or only to help find programmer errors (second version, as asserts will be skipped if you pass the -O "optimized" flag to the python interpreter).

like image 172
Joe Avatar answered Jan 08 '23 15:01

Joe


Returning a value (even None) from a constructor is not allowed

As you suggested, should raise an exception.

class Triangle:
    def __init__(self, a, b, c):
        sides = [a, b, c]
        sides.sort()
        if sides[0]+sides[1] < sides[2]:
            raise ValueError()
        self._a = a
        self._b = b
        self._c = c
like image 23
Sylvain Leroux Avatar answered Jan 08 '23 17:01

Sylvain Leroux