[英]How to increase return values of functions without breaking legacy code?
例如,假设您有一个 function:
def foo(a):
return a
还有大量遗留代码使用这个 function:
amount = 4 + foo(a)
如果我需要在不破坏现有代码的情况下增加foo
的返回值怎么办?
def foo(a)
return a, a + 5
现在,当我这样做时,可变amount
不是正确答案,因为a
现在是,用 pylint 的话来说是“元组”,所以amount
将从返回a + 4
变为返回(a, a+5) + 4
。
如何将a + 5
添加到foo
,同时仍然允许数量是单个标量值,而不是元组?
也许这样的事情会起作用:
def foo(a, new_usage=False):
if not new_usage:
return a
return a + 5
然后针对所有新的使用情况调用您的函数:
foo(a, True)
例如,您的旧代码仍然有效:
In [40]: amount = 4 + foo(4)
In [41]: amount
Out[41]: 8
对于新用法,您可以这样做:
In [42]: amount = 4 + foo(4, True)
In [43]: amount
Out[43]: 13
更优雅的解决方案是使foo
成为扩展int
(或float
,取决于遗留foo()
的输出)的类,而实现__iter__
方法以允许在序列上下文中使用时将其解压缩为序列:
class foo(int):
def __iter__(self):
return iter((self, self + 5))
以便:
amount = 4 + foo(1) # used as an int
print(amount)
a, b = foo(1) # used in a sequence context so foo.__iter__ is called
print(a, b)
输出:
5
1 6
但是当然,上面的代码只是因为在你的问题中, foo(a)
只返回a
,而恰好是int
构造函数的行为,所以通过扩展int
, foo(a)
也方便地返回a
。
但是,如果您的foo(a)
实际上返回a
生成遗留代码中的a
以外a
任何内容,则需要覆盖__new__
方法,以便它返回不同值的新int
实例。
下面显示了一个示例,如果您的遗留foo(a)
返回a + 1
:
class foo(int):
@classmethod
def __new__(cls, type, a):
return super(foo, cls).__new__(type, a + 1)
def __iter__(self):
return iter((self, self + 5))
以便:
amount = 4 + foo(1)
print(amount)
a, b = foo(1)
print(a, b)
输出:
6
2 7
重命名 function 并添加新的返回值。 然后编写一个命名为原始 function 的包装器,它提取遗留的返回值:
原始代码:
def foo(x):
return a
新代码:
def enhanced_foo(x):
return a, extra_info
def foo(x):
return enhanced_foo(x)[0]
旧代码仍然有效:
a = foo(x)
新代码使用新名称:
a, extra = enhanced_foo(x)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.