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__
?
source to share
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
source to share
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)
source to share