这个问题具有一般性。假设您有许多调用某些内部库的微服务。该库具有核心功能((=SUM(B6:B17)
在某些情况下,该函数的反应应有所不同。 那么什么是好的做法?
我有一些想法:
core_function(arg_1,arg_2,..)
。
缺点:应该重构许多微服务。微服务是类。所以我将不得不为每个类引入一个新参数
(或至少一个默认参数)并在调用
功能(当然仅适用于需要修改行为的微服务)在库中添加一些全局变量,例如
behavior_param
可能在__init__文件中。缺点:我会有一个全局参数,但是不喜欢这样。
使用环境变量。这就像第二种解决方案。但是以某种方式我更喜欢这个主意
您怎么看?希望问题清楚。我正在用python寻找最佳,最自然的方法。
答案 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