прямоугольник(точка1, точка2) и отрезок(точка1, точка2)
Хочу чтобы можно было проверить, пересекаются ли объекты этих типов
* Точка пересекается с прямоугольником (лежит внутри)
* отрезок пересекается с отрезком
* отрезок пересекается с прямоугольником (лежит внутри хотя бы частично)
* прямоугольник пересекается с прямоугольником хотя бы частично
* ... возможно что-то еще
* если метод не реализован (например "точка лежит в отрезке") - бросать исключение.
Хочу чтобы проверки проходили как myLine.is_intersects_with(myBox)
При этом совсем не хочу в каждом классе делать is_intersects_with и писать условия для всех вариантов isinstanceof(other, Box).... elif isinstanceof(other, Segment) ... else
Хочу сделать так:
Все три класса - Point, Rect и Segment унаследовать от общего класса GeomPrimitive
В каждом классе прописать protected-методы для нахождения пересечения себя с другими типами примитивов соответственно именам классов
При этом дублировать код - прописывать в классе Box._is_intersects_with_segment и Segment._is_intersects_with_box я не хочу,
То есть хочу что если нет метода Box._is_intersects_with_segment то следует поискать метод Segment._is_intersects_with_box прозрачно для кода.
Соответственно прописать
class Segment:
def _is_intersects_with_box(self, other: Box)
def _is_intersects_with_segment(self, other: Point)
class Box:
def _is_intersects_with_point(self, other: Point)
def _is_intersects_with_box(self, other: Box)
И поиск нужного метода осуществлять в базовом классе GeomPrimitive через формирование названия метода как строки и поиска через getattr примерно так:
class GeomPrimitive:
def is_intersects_with(self, other_geom) -> bool:
method = getattr(self, f"_is_intersects_with_{str.lower(other_geom.__class__.__name__)}", None)
if callable(method):
return method(other_geom)
else:
method = getattr(other_geom, f"_is_intersects_with_{str.lower(self.__class__.__name__)}", None)
if callable(method):
return method(self)
raise NotImplementedError("Method instersection is not implemented between " +
f"{self.__class__.__name__} and {other_geom.__class__.__name__}.")
Вопрос - это адовый трешак так делать? Какие плюсы\минусы\камни в почках?
Как сделать более правильно, не увеличивая кодовую базу?
Тебя на pastebin заблокировали?
Имхо не стоит в гетаттр запихивать ф строки, имхо дичь
Слишком много черточек, в глазах рябит
Слишком много магии
Ну там в целом какое то антиооп...
Почему нельзя сделать is_intersects и если вернул NotImplemented дергать у второго объекта?
Чтобы в каждом классе не писать кучу IF-ов def is_instersects(self, other): if isinstance(other, Box): return self.__is_intersects_with_box(other) elif isinstance(other, Segment): return self.__is_intersects_with_box(other) raise NotImpl Хочется это как-то в более универсальное решение затолкать, наверное. И спасибо за хорошую идею с ловлей.
А в базовый класс нельзя вынести?
Или вообще в отдельную функцию, которая будет пытаться вызывать нужные методы
Сравнение одного типа с другим - "везде своя логика".
Я пока не очень понимаю как это будет расширяться, но наверно в такой формулировке твой вариант допустим
Выглядит так, будто бы нужно использовать functools.singledispatch
Ну кстати, хорошая мысль
А он работает с методами?
Есть singledispatchmethod
Спасибо, кажется то, что нужно. Пошел изучать
Спасибо большое, всё что нужно получилось!
Обсуждают сегодня