170 похожих чатов

Вопрос по перегрузке методов отчасти: Есть три типа примитивов - точка(x,y),

прямоугольник(точка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__}.")

Вопрос - это адовый трешак так делать? Какие плюсы\минусы\камни в почках?
Как сделать более правильно, не увеличивая кодовую базу?

18 ответов

7 просмотров

Тебя на pastebin заблокировали?

Имхо не стоит в гетаттр запихивать ф строки, имхо дичь

Слишком много черточек, в глазах рябит

Слишком много магии

Tishka17
Слишком много магии

Ну там в целом какое то антиооп...

Почему нельзя сделать is_intersects и если вернул NotImplemented дергать у второго объекта?

Alexey D.-Filimonov Автор вопроса
Tishka17
Почему нельзя сделать is_intersects и если вернул ...

Чтобы в каждом классе не писать кучу 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 Хочется это как-то в более универсальное решение затолкать, наверное. И спасибо за хорошую идею с ловлей.

Alexey D. Filimonov
Чтобы в каждом классе не писать кучу IF-ов def is_...

Или вообще в отдельную функцию, которая будет пытаться вызывать нужные методы

Alexey D.-Filimonov Автор вопроса
Tishka17
А в базовый класс нельзя вынести?

Сравнение одного типа с другим - "везде своя логика".

Alexey D. Filimonov
Сравнение одного типа с другим - "везде своя логик...

Я пока не очень понимаю как это будет расширяться, но наверно в такой формулировке твой вариант допустим

Выглядит так, будто бы нужно использовать functools.singledispatch

Alexey D.-Filimonov Автор вопроса
Alexander
Выглядит так, будто бы нужно использовать functool...

Спасибо, кажется то, что нужно. Пошел изучать

Alexey D.-Filimonov Автор вопроса
Alexander
Выглядит так, будто бы нужно использовать functool...

Спасибо большое, всё что нужно получилось!

Похожие вопросы

Обсуждают сегодня

Комрады, посоветуйте, куда копать? Стал прикручивать кастомизацию тем. В OnShow главной главной формы пытаюсь загрузить из файла настроек и применить тему (на скрине, как долж...
Ed Doc
13
OnShow один раз вызывается? или возможен Hide?
Iluha Companets
14
Такс, блин, таки кто-то знает, каким образом работают макросы stdin/stdout/stderr? Я влез в stdio.h, там определения нет, отладил через асмокод - вызывается функция со странны...
The Bird of Hermes
18
я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
Всем привет, на линуксе лучше на fasm или nasm учиться писать для начала ?
meszjol
14
Если у меня есть такой класс: Object = {} function Object:new(a_name, a_transform, a_color, a_mesh, a_material, a_shader, a_textures) local private = {} private.n...
Cuarno Vile
4
@sand_witch скорее к тебе вопрос, добавил в .cabal webdriver-w3c и вот такая ошибка от nix develop error: Package ‘script-monad-0.0.4’ in /nix/store/7vdxbra0kwbr0ys0kc5...
Fedor
5
А еще в перле можно уже @arr1 + @arr2?
Sergei Zhmylove
53
@MrMiscipitlick А можешь макрос написать, который будет вычислять смещение относительно переданных меток? Просто .label1-.label2, и вернуть значение.
КТ315
35
зачем же переименовывать ? чтобы кол-во участников возросло или вдруг IBM от этого снова на свифте начнет кодить ? Я не понимаю что страшного в том что свифт гавно, если это т...
Oleh Nerzh
10
Карта сайта