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 ответов

26 просмотров

Тебя на 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...

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

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта