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

时间:2016-01-02 02:47:43

标签: python python-3.x annotations type-hinting

问题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;它的值总是int s)。

选项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:

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

from typing import TypeVar
from my_module import Foo

FooTypeAlias = TypeVar('FooTypeAlias', Foo[str])

1 个答案:

答案 0 :(得分:2)

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和 所有输入都将来自tg.Mapping,具体如下: 如果您声明例如

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

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