Python 返回赢得';如果我开始返回更多数据,则不会中断客户端代码

Python 返回赢得';如果我开始返回更多数据,则不会中断客户端代码,python,iterable-unpacking,Python,Iterable Unpacking,假设您正在编写一个打算公开的API。API中的函数qux返回一个列表或元组生成器,例如yield(foo,bar) 客户端代码通常会这样使用它: for foo, bar in quux(whatever): # do stuff with foo and bar 现在,假设将来您可能希望开始返回baz以及foo和bar。你不想现在就归还它,因为雅格尼除非证明不是这样 (尝试)确保将来这样的更改不会破坏客户端代码的最佳方法是什么 我知道Python3允许人们在quux(无论什么)中为f

假设您正在编写一个打算公开的API。API中的函数
qux
返回一个列表或元组生成器,例如
yield(foo,bar)

客户端代码通常会这样使用它:

for foo, bar in quux(whatever):
    # do stuff with foo and bar
现在,假设将来您可能希望开始返回
baz
以及
foo
bar
。你不想现在就归还它,因为雅格尼除非证明不是这样

(尝试)确保将来这样的更改不会破坏客户端代码的最佳方法是什么

我知道Python3允许人们在quux(无论什么)中为foo,bar,*idontcare做
,在Python2中,人们总是可以编写一个实用函数(像这样在iterleft(quux(无论什么)中为foo,bar使用
):


但是我想知道是否有更好的方法来做这样的事情。

问题是,您有语义数据(“元组的第一个元素表示x,第二个元素表示y,…”),而您没有将其与数据一起传递

解决此问题的一般方法是返回参数的字典
{“foo”:foo,“bar”:bar,…}
。当然,你不能使用元组解包

否则,为了保持向后兼容性,您不能更改
qux
。相反,您可以使用生成
(foo,bar,baz)
元组的
qux\u来编写
qux\u,然后让
qux
只过滤其中的前两个元素。

返回一个元组而不是常规元组,并且您不需要解压缩它。然后,您可以在不影响API现有用户的情况下扩展返回的元组:

from collections import namedtuple

QuuxReturnValue = namedtuple('QuuxReturnValue', ('foo', 'bar'))

def quux(*args, **kw):
    while True:
        yield QuuxReturnValue(foo='foo', bar='bar')
您的API的使用方式如下:

for retval in quux():
    print retval.foo, retval.bar

如果您稍后更新
名称耦合
以添加第三个参数
'baz'
,则上述使用者仍然可以工作。

“destructuring”更像是一个闭包和javascript 1.7术语;在python中,我们称之为元组解包。谢谢!我看了“解包”,没有想到要找“元组解包”:@MartijnPieters:我认为返回一个名为
的元组是一个好主意,因为返回值不需要解包。@martineau:的确,这是一个答案。@MartijnPieters:如果你没有…;-)
for retval in quux():
    print retval.foo, retval.bar