为什么输入模块会导出“子模块”?

时间:2018-11-03 01:50:16

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

typing模块将两个类iore导出为“伪子模块”,如下所示。通过给它们__all__并将其添加到sys.modules来使它们看起来像模块的目的是什么?

我了解从__all__中将它们排除在外的理由:因此,from typing import *不会掩盖iore,如果它们被导入。

但是为什么将'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

1 个答案:

答案 0 :(得分:2)

最初的目的是键入模块将在标准库中累积许多类的“类型化版本”,例如,Pattern中的typing.re类型或{{1} }输入BinaryIO

在这种情况下,出于组织目的,尝试将这些“幻像类型”命名为子模块式的东西是有意义的。因此,例如,typing.iotyping.re.Pattern类型的规范家,为了方便起见,它将通过Pattern重新导出。

在实践中,这种愿景从未真正实现:我怀疑这部分是因为PEP 484类型检查器的类型推断功能足够复杂,可以使您避免在很多情况下必须明确提供类型提示。因为最终将这些类型直接包含在typing.Pattern或与相关标准库模块相对应的存根中更加方便。

因此,决定(实际上是最近才做出的)仅弃用这两个模块:请参见https://github.com/python/typing/issues/589https://github.com/python/cpython/pull/10173。简而言之,文档上周刚刚更新,从不提及typingtyping.io -新建议是直接从typing.re模块导入相关类型。

可能在将来的Python版本中,这些模块将被完全删除,尽管由于向后兼容的原因它们可能会停留一些时间。