Correct implementation of Python Star Operator for custom class

I have a Python class called Point

which is basically a holder for values x

and y

with added functionality to find distance, angle, etc. with another Point

.

To transfer points to any other function that may require separation x

and y

I would like to be able to use the operator *

to unpack my Point

only separate x

, y

.

I found that this is possible if I override __getitem__

and hoist a StopIterationException

for any index beyond 1, which x

is 0 and y

equal to 1.

However, it does not seem correct to raise a StopIteration

when a ValueError

/ KeyError

would be more appropriate for values ​​greater than 1.

Does anyone know of the correct way to implement an operator *

for a custom class? Preferably, a way that doesn't pick up StopIteration

through __getitem__

?

+3


source to share


2 answers


You can accomplish the same by overriding a magic method __iter__

like this

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __iter__(self):
        return (self.__dict__[item] for item in sorted(self.__dict__))

def printer(x, y):
    print x, y

printer(*Point(2, 3))

      



Output

2 3

      

+4


source


Here's another way to do it, which uses __dict__

but gives you precise control over the order without having to sort by keys for each access:

def __iter__(self): return (self.__dict__[item] for item in 'xy')

      

Sure, you could hide the sorted tuple, list, or string of keys somewhere, but I think using a literal makes sense here.



And while I'm here, the setter and getter methods can be used here.

def __getitem__(self, key): return (self.x, self.y)[key]

def __setitem__(self, key, val): setattr(self, 'xy'[key], val)

      

+1


source







All Articles