如何使用 Python 3.5 的类型提示为 Counter[str] 定义 TypeVar



问题1:

我想使用Python 3.5的类型提示语法定义一个单词袋类型别名,大致如下:

from collections import Counter
from typing import TypeVar
# define bag-of-words type
Bow = TypeVar('Bow', Counter[str])
def process_bag_of_words(bag_of_words: Bow) -> Bow:
    ...

问题是,我不知道如何让Counter接受它的键的类型参数(在本例中为str;它的值总是ints)。

选项1:

由于counter是dict的一个子类,一个替代方案可能类似于:

from typing import TypeVar, Dict
# define bag-of-words type
Bow = TypeVar('Bow', Dict[str, int])

尽管这并不能确保我使用的是Counter而不是Dict

选项2:

另一种选择是将Bow定义为简单的Counter类型,如下所示:

from collections import Counter
from typing import TypeVar
# define bag-of-words type
Bow = TypeVar('Bow', Counter)

不过,这也不是很令人满意,因为它没有在Counter上强制执行密钥类型。

是否有正确的方法来处理这种情况?如果是,那是什么?

问题2:

如果我正在创建自己的类,我怎么能让它接受泛型类型参数呢?因此,如果我在一个名为my_module的模块中声明了一个类Foo,我将如何使其合法:

from typing import TypeVar
from my_module import Foo
FooTypeAlias = TypeVar('FooTypeAlias', Foo[str])

TypeVar的用途是在泛型类或独立泛型函数的声明中充当占位符。

您在问题1中所要查找的内容可能大致如下:

import typing as tg
from collections import Counter
class Bow(Counter, tg.Mapping[str, int]):
    pass

要制作一个通用的"任意物品包"(boas),您可以使用:

import typing as tg
from collections import Counter
S = tg.TypeVar('S')  # STUFF
class Boas(Counter, tg.Mapping[S, int]):
    pass

在这两种情况下,都不需要任何集体机构:所有功能将继承自Counter所有类型都将在以下意义上从CCD_ 11派生:例如,如果您申报

def foo(bag: Bow, what):
    n = bag[what]
    #...

静态类型检查器(如果存在Counter的存根文件或Counter实现中的类型注释)应该能够推断出CCD_ 14将是CCD_可能得出或假设CCD_ 16将是CCD_。动态类型检查器(通过装饰CCD_ 18激活,PyPI typecheck-decorator软件包将很快提供合适的东西)可能会在调用foo时查看实际的bag对象并检查部分或全部密钥为CCD_ 22对应的值为CCD_ 23。

最新更新