Как я могу реализовать полиморфные арифметические операторы pythonicly? - PullRequest
4 голосов
/ 03 марта 2010

Я пытаюсь создать класс, который позволит мне добавлять / умножать / делить объекты одного и того же класса вместе или добавлять / умножать числовые аргументы для каждого члена класса

Так что мой класс для координат (я знаю, что есть отличные пакеты, которые делают все, что я хочу лучше, чем я когда-либо мог надеяться, но теперь мне просто любопытно).

class GpsPoint(object):
    """A class for representing gps coordinates"""
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    def __add__(self, other):
        return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
    def __radd__(self, other):
        return GpsPoint(self.x + other, self.y + other, self.z + other)
    def __str__(self):
        return "%d, %d, %d" % (self.x, self.y, self.z)

Это была моя первоначальная попытка. Я нашел, что это сработало, но только если я сначала использовал числовой аргумент

>>foo = GpsPoint(1,2,3)
>>print 5 + foo
6, 7, 8
>>print foo + 5
AttributeError: 'int' object has no attribute 'x'

Итак, как же питонский способ сделать это, есть ли питонический способ, это просто глупо? Я вижу, в чем философская проблема с использованием isinstance(), и я знаю, что могу бросить в try except блок. Мне просто любопытно, как я должен пойти по этому поводу.

Ответы [ 3 ]

6 голосов
/ 03 марта 2010

«Питонический» способ - «просить прощения, а не разрешения», то есть вместо того, чтобы заранее проверять тип, попробуйте добавить и, в случае неудачи, перехватить исключение и обработать его, например, так:

class GpsPoint(object):
    """A class for representing gps coordinates"""
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    def __add__(self, other):
        try:
            return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
        except AttributeError:
            return GpsPoint(self.x + other, self.y + other, self.z + other)
    def __radd__(self, other):
        try:
            return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
        except AttributeError:
            return GpsPoint(self.x + other, self.y + other, self.z + other)
    def __str__(self):
        return "%d, %d, %d" % (self.x, self.y, self.z)
2 голосов
/ 03 марта 2010

Вам нужно будет попытаться определить тип other, по крайней мере, в той степени, в которой он совместим с GpsPoint. Если вы не можете понять это, просто верните NotImplemented, и интерпретатор попытается обработать это оттуда.

0 голосов
/ 03 марта 2010

Краткий ответ: используйте isinstance ().

Нет другого способа определить тип "другой" в ваших методах. Также, если вы проверите источники многих библиотек Python, вы обнаружите, что во многих местах используется isinstance (). Так что это просто состояние искусства в Python :-).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...