I have a Python class called Point
, that is basically a holder for an x
and y
value with added functionality for finding distance, angle, and such with another Point
.
For passing a point to some other function that may require the x
and y
to be separate, I would like to be able to use the *
operator to unpack my Point
to just the separate x
, y
values.
I have found that this is possible if I override __getitem__
and raise a StopIterationException
for any index beyond 1, with x
corresponding to 0 and y
to 1.
However it doesn't seem proper to raise a StopIteration
when a ValueError
/KeyError
would be more appropriate for values beyond 1.
Does anyone know of the correct way to implement the *
operator for a custom class? Preferably, a way that does not raise StopIteration
through __getitem__
?
You can implement the same by overriding the __iter__
magic method, 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
Here's another way to do it that uses __dict__
but gives you precise control over the order without having to perform a sort on the keys for every access:
def __iter__(self): return (self.__dict__[item] for item in 'xy')
Of course, you could stash a sorted tuple, list or string of keys somewhere, but I think using a literal makes sense here.
And while I'm at it, here's one way to do the setter & getter methods.
def __getitem__(self, key): return (self.x, self.y)[key]
def __setitem__(self, key, val): setattr(self, 'xy'[key], val)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With