【发布时间】:2020-08-16 10:49:47
【问题描述】:
名称Counter 在collections(作为类)和typing(作为通用类型名称)中都定义了。不幸的是,它们略有不同。处理此问题的推荐方法是什么?
异同:
-
在
from collections import Counter之后,- 您可以调用构造函数
Counter("foo")来创建一个新的Counter对象; - 你可以验证它是
dict的子类:issubclass(Counter, dict)返回True; - 您不能使用它来声明
Counter的特定变体,例如cnt: Counter[str] = Counter("foo")raisesTypeError: 'type' object is not subscriptable(类型提示失败)
- 您可以调用构造函数
-
在
from typing import Counter之后,- 您可以调用构造函数
Counter("foo")来创建一个新的Counter对象(实际上,有点令我惊讶); - 你不能用它来验证它是
dict的子类:issubclass(Counter, dict)raisesTypeError: issubclass() arg 1 must be a class; - 您可以声明
Counter的特定变体,例如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
并使用
-
co.Counter或Counter作为构造函数 - 使用
co.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
给你所有。
我是否忽略了什么?
【问题讨论】:
-
您可以添加另一个:
import collections as co; c = co.Counter('this is a good question') -
为什么不使用完全导入? typing.Counter 和 Collections.Counter 很容易区分并提供更好的可读性。
-
@MortenB 我在教育环境中需要这个,与刚开始学习编程的学生一起。这似乎是一种不必要的复杂化,尤其是因为其他类型不需要这种方法。
标签: python collections counter type-hinting