函数如何在Python中返回一个依赖接收者数量的动态值?

2 投票
6 回答
789 浏览
提问于 2025-04-17 07:19

我在尝试做一个“奇怪”的(但对我来说很有用)函数,它可以返回一个动态列表,这个列表的长度取决于接收者的数量。

举个例子:

f() 返回一个包含 None 的动态列表,这样我就可以这样做:

a = f()  => a = None
a, b = f()  => a=b= None
(a, b) = f() => a=b= None
(a, b, c, d, e, f) = f()  => a=b=c=d=e=f= None

我觉得这可能可以通过生成器表达式或迭代器来实现,但我不知道怎么获取接收者的数量。也许我走错方向了。你能给我一些建议吗?

任何帮助都非常感谢。

非常感谢,

Tiezhen

6 个回答

1

如果你不介意使用Python 3的话,你可以忽略那些你不需要的部分,比如:

a, b, c, d, *_ = (x for x in range(100))
3

在Python中,这是不可能的。右边的函数在被调用时并不知道它是在什么环境下被调用的。右边的部分在任何变量绑定之前就已经被计算了。

1

很遗憾,Python 在处理返回的元组时采用了一种“先求原谅再求许可”的方式。这是什么意思呢?就是如果你有这样一句代码:

a,b,c = f()

在后台,它其实是做了类似这样的事情:

try:
    a = returned[0]
    b = returned[1]
    c = returned[2]
except IndexError:
    raise ValueError('need more than k values to unpack')

try:
    _ = returned[4]
except IndexError:
    pass
else:
    raise ValueError('too many values to unpack')

所以它会动态地发现返回了多少个值。不幸的是,这样的做法让我们无法聪明地创建一种新类型来处理可变返回值:

class VariableReturn(object):
    def __getitem__(self, index):
        return ...

在 Python 3 中,你可以做到你想要的那样,但责任在于调用者,而不是被调用的函数。函数应该总是返回相同数量的结果,但我们可以用扩展元组解包来捕捉剩下的结果,具体可以参考这个 StackOverflow 问题

使用这种方法,你可以返回任意数量的结果,但你需要确保在最极端的情况下至少返回你需要的数量。剩下的结果会被打包成一个尾随的元组。

a,*others = f()
a,b,*others = f()
a,b,c,*others = f()

撰写回答