special method for an object to override tuple exp

2019-05-30 21:07发布

问题:

I will provide an example of the problem in question, in case the title was not clear enough.

Let's say that I have a class Point(object) that represent 2d coordinates. Is it possible to create a "magic" method that will allow the following?

x, y = point

Maybe some hacks with iterators?

回答1:

Just provide an __iter__ method.

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

p = Point(1, 2)
x, y = p
assert (1, 2) == (x, y)

Be careful though. This means your class suddenly becomes safe to use in many other places where it might have previously thrown a type error.

eg.

def add_1(x):
    return x + 1
l = list(map(add_1, p)) # works, because the point is iterable

Ergo, you may want to provide a method other than __iter__ that provides the iterator.

eg.

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

p = Point(1, 2)
x, y = p.coords()
assert (1, 2) == (x, y)


回答2:

you can simply tap into the iterator protocol of the object and accomplish this

class Point(object):
    def __init__(self, x,y):
        self.x = x
        self.y = y
        self.points = (x,y)
    def __iter__(self):
        return iter(self.points)

p = Point(1,5)
x,y = p
print x,y
# 1,5

take a look at http://www.rafekettler.com/magicmethods.html#sequence on more information on how a custom object can be converted into an iterable; or more precisely how one would use an object like an iterable.