Определение глобального поведения функции?Хорошая практика - PullRequest
0 голосов
/ 18 декабря 2018

этот вопрос носит общий характер.Предположим, у вас много микросервисов, вызывающих некоторую внутреннюю библиотеку.Эта библиотека имеет базовую функцию core_function(arg_1,arg_2,..)

В некоторых случаях функция должна реагировать немного по-другому.Так что было бы хорошей практикой?

Некоторые идеи, которые у меня есть:

  1. Добавить аргумент в функцию.behavior_param.Недостаток: многие микросервисы должны быть реорганизованы.Микросервисы - это классы.Поэтому мне нужно будет ввести новый параметр для каждого класса (или, по крайней мере, параметр по умолчанию) и использовать его при вызове функции (конечно, только для микросервисов, которым требуется измененное поведение)
  2. Добавитьнекоторая глобальная переменная в библиотеке, такая как behavior_param, может быть, в файле __init__.Недостаток: у меня был бы глобальный параметр, и он мне не нравился.

  3. Использование переменных окружения.Это как второе решение.Но почему-то мне нравится эта идея лучше

Что вы думаете?Надеюсь, вопрос ясен.Я ищу лучший и самый естественный подход к этому в python.

Ответы [ 3 ]

0 голосов
/ 18 декабря 2018

Флаги, которые изменяют поведение, будь то глобальные переменные или параметры функции, в порядке, но если они приводят к слишком большому разветвлению (if s) в коде функции, я предпочитаю иметь группу функций, каждаяодин, обеспечивающий одно из желаемых поведений, и фабричную функцию, которая возвращает правильную функцию на основе значения флага.

Это отделяет выбор правильного поведения от реализации поведения.

Например,, что-то вроде этого:

def factory(arg0, arg1 ..., flag):
   func_map = {
        0: func0,
        1: func1,
        2: func2
   }
   return func_map[flag](arg0, arg1)

result = factory(foo, bar, 1)

Я бы не стал этого делать, если есть только два возможных поведения, но определенно рассмотрел бы для трех или более.

0 голосов
/ 18 декабря 2018

Вот мое решение вышеуказанной проблемы.Обратите внимание, что решение с параметром по умолчанию является стандартным способом.Это решение полезно, если есть несколько функций, которые должны реагировать на поведение по умолчанию.

_default_behavior = { "arg_1": value_1, "arg_2": value_2}

def set_default_behavior(value_1, value_2):
   _default_behavior["arg_1"] = value_1
   _default_behavior["arg_2"] = value_2

def core_function():
   if _default_behavior["arg_1"] == True:
      # do some stuff and also arg_2 may be used
      pass 
   else: 
      # here is the default case
      pass 
0 голосов
/ 18 декабря 2018

Ваша интуиция верна - избегайте использования глобальных переменных для динамического изменения поведения core_function.Вообще говоря, они сделают ваш код сложнее для других, труднее поддерживать и более хрупким.Используйте их как опцию последней инстанции.

Если вы хотите изменить поведение core_function без повторного факторинга всех случаев, когда core_function уже вызван, то вы должны добавить необязательный аргумент для core_function и укажите значение по умолчанию.Этот необязательный аргумент диктует «режим поведения», которому должна следовать функция.

Измените это:

def core_function(arg_1, arg_2):

На это:

def core_function(arg_1, arg_2, behavior_param = 'Default'):

Это позволит существующимкод для продолжения использования core_function с поведением по умолчанию и без повторного факторинга.Для будущего кода вы можете указать необязательный аргумент и указать желаемое поведение.

...