我一直在无类型 Python 中使用生成器,而不是返回列表。例如,在 Python 3.11 中:
def generate_plant():
"""
Generates fields for a sunflower.
"""
# label
yield 'A1'
# height in inches
yield 72
# hours of sunlight daily
yield 8.5
def get_plant():
"""
Returns fields as a tuple.
"""
return ('A1', 72, 8.5)
# save the results
from_generator = tuple(generate_plant())
direct_tuple = get_plant()
# compare
print('From generator:', from_generator)
print('Directly from tuple:', direct_tuple)
print('Are they equal?', from_generator==direct_tuple)
这里
from_generator
和 direct_tuple
应该具有相同的值并且相等。
这让我可以在调用者处选择我想要的集合类型,或者我是否只想要前几个字段。
但是,当谈到打字时,我相信
collections.abc
中的生成器与其他可迭代对象一样是同质的,除了元组的特殊情况。
所以,我认为我能得到的最接近的类型是输入
def generate_plant() -> collections.abc.Iterator[str | int | float]
。然而,这仍然太笼统,并且没有像 def get_plant() -> tuple[str, int, float]
那样理解字段类型的顺序。
目前这是选择一种情况(异构生成器)还是另一种情况(打字),或者有没有办法表示生成器应该返回一个字符串,然后返回一个整数,然后返回一个浮点数?甚至是滥用生成器来使其变得异构吗?
到目前为止,可以选择输入
def generate_plant() -> collections.abc.Iterator[str | int | float]
,或者像 get_plant()
一样直接使用元组。
我希望有一种方法来指定一个按顺序返回字符串、整数和浮点数的生成器。
甚至是滥用生成器来使其变得异构吗?
我认为这是一种误用,因为如果您收到这样的迭代器,就无法知道接下来会出现 3 种类型中的哪一种,因为不能保证它之前没有被迭代过 3 的倍数。
这让我可以在调用者处选择我想要的集合类型,或者我是否只想要前几个字段。
返回一个元组应该没问题,因为您始终可以将其转换为不同的集合,或者使用切片和/或解包分配来仅使用某些字段,例如:
label, height = get_plant()[:2]
label, _, hours = get_plant()