在 Python 中键入异构生成器

问题描述 投票:0回答:1

我一直在无类型 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()
一样直接使用元组。

我希望有一种方法来指定一个按顺序返回字符串、整数和浮点数的生成器。

python generator python-typing
1个回答
0
投票

甚至是滥用生成器来使其变得异构吗?

我认为这是一种误用,因为如果您收到这样的迭代器,就无法知道接下来会出现 3 种类型中的哪一种,因为不能保证它之前没有被迭代过 3 的倍数。

这让我可以在调用者处选择我想要的集合类型,或者我是否只想要前几个字段。

返回一个元组应该没问题,因为您始终可以将其转换为不同的集合,或者使用切片和/或解包分配来仅使用某些字段,例如:

label, height = get_plant()[:2]
label, _, hours = get_plant()
© www.soinside.com 2019 - 2024. All rights reserved.