繁体   English   中英

如何在不破坏遗留代码的情况下增加函数的返回值?

[英]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构造函数的行为,所以通过扩展intfoo(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM