名称Counter是在collections (作为类)和typing (作为泛型类型名称)中定义的。不幸的是,它们略有不同。建议的处理方法是什么?
异同点:
from collections import Counter,1. you can call the constructor `Counter("foo")` to create a fresh `Counter` object;
2. you can verify that it is subclass of `dict`: `issubclass(Counter, dict)` returns `True`;
3. you cannot use it to declare a specific variant of `Counter`, e.g. `cnt: Counter[str] = Counter("foo")` raises `TypeError: 'type' object is not subscriptable` (the type hint fails)
from typing import Counter,1. you can call the constructor `Counter("foo")` to create a fresh `Counter` object (actually, somewhat to my surprise);
2. you cannot use it to verify that it is subclass of `dict`: `issubclass(Counter, dict)` raises `TypeError: issubclass() arg 1 must be a class`;
3. you can declare a specific variant of `Counter`, e.g. `cnt: Counter[str] = Counter("foo")`.
在许多情况下,1.1和2.1已经足够好了,所以导入的选择并不重要。但是,似乎不能同时使用1.3和2.2来处理单个导入。在后两者中,类型提示比子类检查更重要。如果您想编写类型提示,那么from typing import Counter就足够了。不过,如果您编写的话,我会发现它更清晰(更符合其他类型所需的内容)
from collections import Counter # to indicate that you want the implementation
from typing import Counter # to indicate that you want to write type hints(注意该命令是重要的。)。
如果你想拥有一切呢?以下是我看到的选择:
from collections import Counter
import typing并利用typing.Counter实现了1.3分。不太好,太冗长了。
import collections
from typing import Counter并使用collections.Counter实现2.2 (如果需要的话,我在教学中需要它)。
from collections import Counter as counter
from typing import Counter并利用counter实现了2.2。
from collections import Counter
from typing import Counter as Bag # or Multiset并在提示类型中使用Bag (或Multiset)。(但这肯定会让人困惑。)
import collections as co # to access the class
from typing import Counter # to access constructor and provide type hints并使用
作为类的constructor
co.Counter或Counter,例如类型提示中的issubclass(co.Counter, dict)
Counter,例如cnt: Counter[str]那么,是否也建议这样做呢?
from typing import Deque并使用Deque作为构造函数,而不是使用co.deque?(我想/希望不是。)
对于其他类型(如defaultdict和deque),这似乎不是一个问题:
from collections import defaultdict, deque
from typing import DefaultDict, Deque给你们所有人。
我是不是忽略了什么?
发布于 2021-12-24 17:17:58
从Python3.9开始,您可以:
from collections import Counter
c: Counter[str] = Counter()请参阅:https://docs.python.org/3/library/typing.html#typing.Counter
自3.9版以来,
就不再受欢迎了: collections.Counter现在支持[]。参见PEP 585和通用别名类型.
发布于 2020-05-01 21:41:44
可能有一些更高级的情况下,这是行不通的,但您可以创建一个子类,从这两个子类继承:
import typing
import collections
KT = typing.TypeVar("KT")
class Counter(collections.Counter, typing.Counter[KT]): pass
c: Counter[str] = Counter("foo")
print(isinstance(c, dict)) # True发布于 2020-05-01 22:25:08
最少的痛苦可能是满足于基于字符串的类型暗示。然而,并不是每个IDE都会解释它;PyCharm在这段代码段的最后一行检测到类型不匹配,而VSCode认为一切都很好。
from collections import Counter
mycounter: 'Counter[str]' = Counter('foo')
def func1(counter: 'Counter[str]'):
pass
def func2(counter: 'Counter[int]'):
pass
func1(mycounter)
func2(mycounter)https://stackoverflow.com/questions/61551094
复制相似问题