定义函数的全局行为?好的做法

时间:2018-12-17 21:22:39

标签: python design-patterns architecture

这个问题具有一般性。假设您有许多调用某些内部库的微服务。该库具有核心功能((=SUM(B6:B17)

在某些情况下,该函数的反应应有所不同。 那么什么是好的做法?

我有一些想法:

  1. 向函数添加参数。 core_function(arg_1,arg_2,..)。 缺点:应该重构许多微服务。微服务是类。所以我将不得不为每个类引入一个新参数 (或至少一个默认参数)并在调用 功能(当然仅适用于需要修改行为的微服务)
  2. 在库中添加一些全局变量,例如 behavior_param可能在__init__文件中。缺点:我会有一个全局参数,但是不喜欢这样。

  3. 使用环境变量。这就像第二种解决方案。但是以某种方式我更喜欢这个主意

您怎么看?希望问题清楚。我正在用python寻找最佳,最自然的方法。

3 个答案:

答案 0 :(得分:4)

您的直觉是正确的-避免使用全局变量来动态修改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且具有默认行为,而无需任何重构。对于以后的代码,您可以提供可选参数并指定所需的行为。

答案 1 :(得分:1)

可以改变行为的标记,无论它们是全局变量还是函数参数都可以,但是如果它们导致函数代码中的分支过多(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)

如果只有两种可能的行为,我不会这样做,但肯定会考虑三种或更多。

答案 2 :(得分:0)

这是我解决上述问题的方法。注意,使用默认参数的解决方案是标准方法。如果有多个功能应对某些默认行为,则此解决方案很有用。

_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