#python #design-patterns
Вопрос:
Это действительно вопрос дизайна, и я хотел бы немного узнать, какие шаблоны дизайна использовать.
У меня есть модуль, скажем curves.py
, который определяет Bezier
класс. Затем я хочу написать функцию intersection
, которая использует рекурсивный алгоритм для поиска пересечений между двумя экземплярами Bezier
.
Какие у меня есть варианты для размещения этих функций? Каковы некоторые лучшие практики в этом случае? В настоящее время я написал функцию в самом модуле (а не как метод для класса).
Так что в настоящее время у меня есть что-то вроде:
def intersections(inst1, inst2): ...
def Bezier(): ...
и я могу вызвать функцию, передав два экземпляра:
from curves import Bezier, intersections
a = Bezier()
b = Bezier()
result = intersections(a, b)
Однако другим вариантом (который я могу придумать) было бы создание intersection
метода класса. В этом случае я бы вместо этого использовал
a.intersections(b)
Для меня первый выбор имеет немного больше смысла, так как кажется более естественным позвонить intersections(a, b)
, чем a.intersections(b)
. Однако другой вариант кажется более естественным в том смысле, что функция intersection
действительно действует только на Bezier
экземпляры, и это кажется более инкапсулированным.
Считаете ли вы, что один из них лучше другого, и в таком случае, по каким причинам? Есть ли здесь какие-либо другие варианты дизайна для использования? Существуют ли какие-либо лучшие практики?
Ответ №1:
В качестве примера вы можете сравнить, как встроенный set
класс делает это:
пересечение(*другие)
набор amp; другое amp; …
Возвращает новый набор с элементами, общими для набора и всех остальных.
So intersection
определяется как обычный метод экземпляра класса, который принимает другие (или несколько) наборов и возвращает пересечение, и его можно назвать как a.intersection(b)
.
Однако из-за стандартной механики работы методов экземпляра вы также можете написать его set.intersection(a, b)
по буквам, и на практике вы будете видеть это довольно часто, так как, как вы говорите, это кажется более естественным.
Вы также можете переопределить __and__
метод, чтобы он стал доступен как a amp; b
.
С точки зрения простоты использования, размещение его в классе также более удобно, потому что вы можете просто импортировать Bezier
класс, и все связанные с ним функции будут доступны автоматически, и их также можно обнаружить с помощью help(Bezier)
.
Комментарии:
1. Это звучит как множество веских причин использовать его в таком дизайне.