Специальный метод для объекта переопределить расширение кортежа?

Я приведу пример рассматриваемой проблемы, если название было недостаточно ясным.

Допустим, у меня есть class Point(object) которые представляют 2d координаты. Можно ли создать "волшебный" метод, который позволит следующее?

x, y = point

Может быть, некоторые хаки с итераторами?

2 ответа

Решение

Просто предоставьте __iter__ метод.

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)

Будьте осторожны, хотя. Это означает, что ваш класс внезапно становится безопасным для использования во многих других местах, где он мог ранее вызвать ошибку типа.

например.

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

Ergo, вы можете предложить метод, отличный от __iter__ это обеспечивает итератор.

например.

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)

Вы можете просто нажать на протокол итератора объекта и выполнить это

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

взгляните на http://www.rafekettler.com/magicmethods.html для получения дополнительной информации о том, как пользовательский объект может быть преобразован в итеративный; или, точнее, как использовать объект как итеративный.

Другие вопросы по тегам