typing
模块将两个类io
和re
导出为“伪子模块”,如下所示。通过给它们__all__
并将其添加到sys.modules
来使它们看起来像模块的目的是什么?
我了解从__all__
中将它们排除在外的理由:因此,from typing import *
不会掩盖io
和re
,如果它们被导入。
但是为什么将'typing.re'
和'typing.io'
添加到sys.modules
?
来自typing.py
的摘要:
import re as stdlib_re
# The pseudo-submodules 're' and 'io' are part of the public
# namespace, but excluded from __all__ because they might stomp on
# legitimate imports of those modules.
# ...
class io:
"""Wrapper namespace for IO generic classes."""
__all__ = ['IO', 'TextIO', 'BinaryIO']
IO = IO
TextIO = TextIO
BinaryIO = BinaryIO
io.__name__ = __name__ + '.io'
sys.modules[io.__name__] = io
Pattern = _alias(stdlib_re.Pattern, AnyStr)
Match = _alias(stdlib_re.Match, AnyStr)
class re:
"""Wrapper namespace for re type aliases."""
__all__ = ['Pattern', 'Match']
Pattern = Pattern
Match = Match
re.__name__ = __name__ + '.re'
sys.modules[re.__name__] = re
答案 0 :(得分:2)
最初的目的是键入模块将在标准库中累积许多类的“类型化版本”,例如,Pattern
中的typing.re
类型或{{1} }输入BinaryIO
。
在这种情况下,出于组织目的,尝试将这些“幻像类型”命名为子模块式的东西是有意义的。因此,例如,typing.io
是typing.re.Pattern
类型的规范家,为了方便起见,它将通过Pattern
重新导出。
在实践中,这种愿景从未真正实现:我怀疑这部分是因为PEP 484类型检查器的类型推断功能足够复杂,可以使您避免在很多情况下必须明确提供类型提示。因为最终将这些类型直接包含在typing.Pattern
或与相关标准库模块相对应的存根中更加方便。
因此,决定(实际上是最近才做出的)仅弃用这两个模块:请参见https://github.com/python/typing/issues/589和https://github.com/python/cpython/pull/10173。简而言之,文档上周刚刚更新,从不提及typing
和typing.io
-新建议是直接从typing.re
模块导入相关类型。
可能在将来的Python版本中,这些模块将被完全删除,尽管由于向后兼容的原因它们可能会停留一些时间。