метод __add__ без if'а
решил сделать класс Vec2:
class Vec2():
def __init__(self, x = 0, y = 0):
self.x, self.y = x, y
def __add__(self, num):
if type(num) == Vec2:
return Vec2(self.x + num.x, self.y + num.y)
return Vec2(self.x + num, self.y + num)
def __str__(self):
return f"{self.x} {self.y}"
И появился вопрос, могу ли я реализовать метод __add__ без if'а?
примерно как в этом коде на c++:
vec2 operator+(vec2& v) {
return vec2(x + v.x, y + v.y);
}
vec2 operator+(double s) {
return vec2(x + s, y + s);
}
Ответы (3 шт):
Тоже вариант, но с if-ом:
def __add__(self, num):
dx = num.x if type(num) == Vec2 else num
dy = num.y if type(num) == Vec2 else num
return Vec2(self.x + dx, self.y + dy)
С помощью декоратора typedispatch из библиотеки fastcore:
from fastcore.dispatch import typedispatch
class _Vec2:
def __init__(self, x=0, y=0):
self.x, self.y = x, y
def __str__(self):
return f"{self.x} {self.y}"
class Vec2(_Vec2):
@typedispatch
def __add__(self, num: _Vec2):
return Vec2(self.x + num.x, self.y + num.y)
@typedispatch
def __add__(self, num):
return Vec2(self.x + num, self.y + num)
print(Vec2(1, 1) + 2)
print(Vec2(1, 1) + Vec2(1, 2))
Вывод:
3 3
2 3
Пришлось выделить отдельный класс _Vec2 из-за того, что если указывать свой же класс в аннотации, то начинает ругаться на необъявленный символ Vec2 (если использовать строковую аннотацию "Vec2" или добавить from __future__ import annotations, то ошибку выкинет внутри fastcore.dispatch).
Обзор библиотеки fastcore: fastcore: An Underrated Python Library
Как вариант:
class Vec2():
def __init__(self, x = 0, y = 0):
self.x, self.y = x, y
def __add__(self, num):
return Vec2(self.x + getattr(num, 'x', num), self.y + getattr(num, 'y', num))
def __str__(self):
return f"{self.x} {self.y}"
Но это будет работать для любого класса, у которого есть член x или y.
А вообще, зачем это надо?