LINUX.ORG.RU

Воженные функции

 ,


0

1

Есть некоторая функция внутри класса,которая может работать по двум разным алгоритмам в зависимости от входных данных. Пользователю не должно быть интересно как она устроена: в обоих алгоритмах будет возвращен один и тот же набор значений. Как лучше скрыть разницу в алгоритмах:

  • Написать две функции внутри класса и третью,которую вызывает пользователь класса ?
  • Написать две функции,определенные внутри той функции, что вызывает пользователь?
★★★★★

Если язык позволяет, я бы предпочел второй вариант, чтобы не засорять интерфейсы.

staseg ★★★★★ ()
Ответ на: комментарий от staseg

позволяет,по тем же соображениям что и у вас склоняюсь ко второму варианту

pylin ★★★★★ ()

Первое будет читабельнее и проще в поддержке.

schizoid ★★★ ()

Первый вариант. “Flat is better than nested”. Другим методам класса может понадобится вызывать специфический алгоритм.

k_andy ★★★ ()

Чтобы не создавать эти две функции при каждом вызове общей функции, используй замыкание и декоратор.

def _decor(f):
    def foo1(a):
        ...
        return res
    def foo2(a):
        ...
        return res
    def wrapper(a):
        if check(a):
            return foo1(a)
        else:
            return foo2(a)
    return wrapper

@_decor
def bar(a): pass
Правда, bar выглядит нелепо, да _decor одноразовый получается.

Virtuos86 ★★★★★ ()
Ответ на: комментарий от k_andy

Кстати да это соображение из zen of python сюда подходит, однако насчет 2-го соображения: для данной программы можно гарантировать, что другие методы класса эти внутренние алгоритмы вызывать не будут

pylin ★★★★★ ()
Ответ на: комментарий от Virtuos86

Спасибо, кстати о декораторах я и не подумал

pylin ★★★★★ ()

Первый по мне так лучше с точки зрения возможности самостоятельного выбора алгоритмов и возможности их тестирования.

Либо можно спрятать из поля видимости две функции в классе, а к функции обертки ещё добавить дополнительный параметр выбора алгоритма со значением по умолчанию, вида, XXXAuto.

AlexVR ★★★★★ ()
Ответ на: комментарий от AlexVR

Полезный прием, однако в данном случае есть математическое правило,которое однозначно решает какой из алгоритмов выбрать

pylin ★★★★★ ()

Callable-класс, алгоритмы (методы) прячешь внутрь.

anonymous ()
Ответ на: комментарий от pylin

if слишком громоздкий получится

Пуркуа? Если там нетривиальные условия выбора алгоритма, то:

def mymethod( self, ... ) :
   mode = .....
   if mode : # alg1
   else : #alg2

По числу строчек так будет ровно то же самое, по читаемости - ИМНО куда прозрачней. Вложенные ф-ии имеют свои особенности, декоратор для этого припахивать так вообще... явный синдром аспектного программирования ГМ;-)

Еще кстати не обязательно делать ф-ю методом класса, она м.б. просто обычной ф-ей модуля принимающей аргументом self экз. класса, и не экспортироваться из модуля по дефолту.

AIv ★★★★★ ()
Ответ на: комментарий от AIv

Под громоздкостью ТС видимо подразумевал тот простой факт, что ветки alg1 и alg2 будут иметь лишний уровень оступов по сравнению с вариантом вынесения их в отдельные функции. «Плоское лучше вложенного» и всё такое. Кроме того, если алгоритмы расписаны на много строк, базовая функция распухнет. Пассаж про синдромы оставлю без комментариев.

Virtuos86 ★★★★★ ()
Ответ на: комментарий от Virtuos86

Ну если отступы заботят, эти ф-ии надо вообще внешними делать.

Про синдромы не обижайтесь - там стоял смайлик.

AIv ★★★★★ ()
Ответ на: комментарий от Virtuos86

Согласен с вами, она действительно сильно распухнет, если писать «все в одном»

pylin ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.