函数如何在Python中返回一个依赖接收者数量的动态值?
我在尝试做一个“奇怪”的(但对我来说很有用)函数,它可以返回一个动态列表,这个列表的长度取决于接收者的数量。
举个例子:
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()