Недавно я прочитал вопросы, которые рекомендуют против использования операторов switch-case на языках, которые его поддерживают. Что касается Python, я видел несколько замен по замене коммутатора, например:
- Использование словаря (многие варианты)
- Использование кортежа
- Использование декоратора функций (http://code.activestate.com/recipes/440499/)
- Использование полиморфизма (рекомендуемый метод вместо объектов проверки типов)
- Использование лестницы if-elif-else
- Кто-то даже рекомендовал шаблон посетителя (возможно, Extrinsic)
Учитывая множество вариантов, я немного затрудняюсь решить, что делать для определенной части кода. Я хотел бы изучить критерии выбора одного из этих методов над другим в целом. Кроме того, я был бы признателен за советы относительно того, что делать в конкретных случаях, когда у меня возникают проблемы с выбором (с объяснением выбора).
Вот конкретная проблема:
(1)
def _setCurrentCurve(self, curve):
if curve == "sine":
self.currentCurve = SineCurve(startAngle = 0, endAngle = 14,
lineColor = (0.0, 0.0, 0.0), expansionFactor = 1,
centerPos = (0.0, 0.0))
elif curve == "quadratic":
self.currentCurve = QuadraticCurve(lineColor = (0.0, 0.0, 0.0))
Этот метод вызывается qt-slot в ответ на выбор рисования кривой из меню. Вышеуказанный метод будет содержать в общей сложности 4-7 кривых, как только приложение будет завершено. В этом случае оправданно использовать броский словарь? Поскольку самый очевидный способ сделать это - если-elif-else, я должен придерживаться этого? Я также рассматриваю использование ** kargs здесь (с помощью друзей), так как все классы кривой используют ** kargs...
(2)
Эта вторая часть кода представляет собой qt-slot, который вызывается, когда пользователь меняет свойство кривой. В основном слот берет данные из gui (spinBox) и помещает его в переменную экземпляра соответствующего класса кривой. В этом случае у меня снова есть тот же вопрос - следует ли использовать dict?
Вот вышеназванный слот
def propertyChanged(self, name, value):
"""A Qt slot, to react to changes of SineCurve properties."""
if name == "amplitude":
self.amplitude = value
elif name == "expansionFactor":
self.expansionFactor = value
elif name == "startAngle":
self.startAngle = value
elif name == "endAngle":
self.endAngle = value
Для справки, вот код для подключения к вышеуказанному слоту -
def _connectToPage(self, page):
for connectionData in page.getConnectibles():
self.connect(connectionData["object"],
SIGNAL(connectionData["signal"]),
lambda value, name = connectionData["property"]:\
self.currentCurve.propertyChanged(name, value))
self.connect(connectionData["object"],
SIGNAL(connectionData["signal"]),
self.hackedDisplayArea.update)
Примечание. В конструкторе инициализируются self.endAngle и т.д.
Насколько я знаю, причины выбора dict - это быстрый поиск. Когда это оправдано? когда у меня есть 100 случаев или больше? Это хорошая идея продолжать строить и отбрасывать словарь каждый раз, когда вызывается функция? Если я построю dict для этой цели вне функции, должен ли я проверить, нужно ли это где-нибудь? Что произойдет, если оно не понадобится в другом месте?
Мой вопрос в том, что является лучшей практикой, если он есть? Каков лучший/самый элегантный способ заниматься вещами? Поставить еще один способ, когда использовать if-elif-else, когда использовать каждый из других параметров?