我有一个类似函数的版本1:
def f(a,b,c):
#Some processing
return some_result
稍后,我将其升级到版本2.
def f(a,b,c):
#Some processing
#Some more processing
return some_result, additional_result
后一版本返回一个元组。因此,使用版本1的所有客户端代码都已过时。我可以按需获得additional_result
吗?
只有在您继续获得additional_result
并且没有任何改变时,您才会获得some_result
。
我想到的一个技巧:
def f(a,b,c, need_additional = False):
#Some processing
#Some more processing
if not need_addional:
return some_result
else:
return some_result, additional_result
还有什么更好的?还是更通用的?
答案 0 :(得分:9)
我认为更优雅的解决方案是让您的旧功能成为新功能的传统包装器:
def f(a,b,c):
some_result, additional_result = f_new(a,b,c)
return some_result
def f_new(a,b,c):
#Some processing
#Some more processing
return some_result, additional_result
我必须承认我主要使用你建议的模式,而不是我的:),但是向后兼容的默认参数并不是很好的练习。
答案 1 :(得分:2)
将additional_result
添加为some_result
如果需要,将some_result
更改为继承其数据类应该是什么的类,但使用additional_result
。
(所以遗留代码可以简单地忽略你的“额外位”)
甚至更好。
只需创建返回多个值的单独函数即可。 亲吻;)
答案 2 :(得分:2)
所提供的解决方案都不是完美的。
实际上,虽然看起来确实很难看,但我想我更喜欢已经提到的通过out-parameters传递额外结果的方法。我的编码方式是:
老来电者:
result = f(a, b, c)
print result
新来电者:
additionalResult = [0]
result = f(a, b, c, additionalResult)
print result, additionalResult[0]
被叫方:
def f(a, b, c, additionalResult=[None]):
#Some processing
#Some more processing
additionalResult[0] = someValue
return some_result
这也是很好的,经常在C中练习,所以有充分的理由相信这不会是我们可能忽略的陷阱,虽然它可能看起来很难看。
答案 3 :(得分:1)
虽然我不是Python专家,但我会以你提到的方式实现它,在我看来,这是一个非常直接的改变,以便允许向后兼容。
答案 4 :(得分:1)
如果您不必在同一文件中同时使用这两个版本,则可以通过包含该方法的2个版本的模块来控制它,然后仅在调用模块中导入所需的版本。然后,当你最终完成并重构旧代码时,你所要做的就是在完成后改变import语句。
或者,在同一模块中使用from x import y as z
构造和两种实现。
答案 5 :(得分:0)
您还可以在字典中返回额外值作为引用,其引用作为额外参数传递,例如:
def f(a,b,c, additional_result_dict = {}):
#Some processing
#Some more processing
additional_result_dict['additional_result'] = additional_result
return some_result
答案 6 :(得分:0)
我终于实现了它:
def f(a,b,c, v2 = False):
#Some processing
#Some more processing
if not v2:
return some_result
else:
v2_dict = {}
v2_dict['additional_result'] = additional_result
v2_dict['...'] = ...
return some_result, v2_dict
<强>优点:强>