framontb
framontb

Reputation: 2077

python conditional constructor for giving object or None

I receive UDP packets with GPS data, and construct Position objects with them. Sometimes, GPS loss satellite signal, but still send UDP packets with no valuable data. I would like the Position constructor gives me a 'None' object in this failure cases. So, I could check if process the Position or not. Something like that:

frameGPS = giveMeTheFrame()
position1 = Position(frameGPS)
if (position1 is None): don't process position1
else: process position1

Is this a right way to do it? If so, how could I implement this init?

Upvotes: 1

Views: 9697

Answers (2)

Silvio Mayolo
Silvio Mayolo

Reputation: 70397

As coldspeed said, you can't return from __init__. What you can do is initialize the object to an "empty" state. Make your Position object do something like this.

class Position:
    def __init__(self, frame):
        if some_condition:
            self.okay = True
            # Success; load the frame data into Position ...
        else:
            self.okay = False
    def __bool__(self):
        return self.okay

Then you can use it in an if-statement like you wanted to.

frameGPS = giveMeTheFrame()
position1 = Position(frameGPS)
if position1:
    # Success; do some work ...
else:
    # Failure; GPS lost signal ...

Note that in Python 2.x, the relevant method is called __nonzero__(), not __bool__(). So, use __nonzero__() if you are in Python 2.x, use __bool__() if you are in Python 3.x

Upvotes: 5

idjaw
idjaw

Reputation: 26600

There are different ways you can approach this. The answer just posted by implementing __bool__ is a very good option too!

To provide another approach as well:

Per your comment on what is considered garbage data, and what is considered valid data. Let us say you receive valid characters as coordinates. To keep it simple:

N, S, E, W

One way, is you can have your class raise if it is given invalid data to properly instantiate an instance of that class:

def Position:
    def __init__(self, position):
        if position.upper() not in {'N', 'S', 'E', 'W'}:
            raise InvalidPositionData('Received unexpected data {}'.format(position))
        self.position = position

In your code, you can simply wrap to catch that exception:

frameGPS = giveMeTheFrame()
try:
    position1 = Position(frameGPS)
except InvalidPositionData as exc:
    # do things with your exception here
    log.error('something bad happened')
# continue with logic here

Upvotes: 3

Related Questions