代码之家  ›  专栏  ›  技术社区  ›  Brad Solomon

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

  •  1
  • Brad Solomon  · 技术社区  · 7 年前

    这个 typing 模块导出两个类, io re ,作为“伪子模块”,转载如下。通过给它们一个简单的例子,让它们看起来像模块的意图是什么 __all__ sys.modules ?

    :所以 from typing import * 木卫一 和

    但为什么要加 'typing.re' 和 'typing.io' 到 ?


    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 回复  |  直到 7 年前
        1
  •  2
  •   Michael0x2a    7 年前

    最初的目的是类型化模块将在标准库中积累许多类的“类型化版本”——例如 Pattern typing.re 或者 BinaryIO typing.io .

    在这种情况下,为了组织的目的,尝试将这些“幻影类型”命名为子模块。比如说, typing.re.Pattern 将是一个典型的家庭 图案 类型,然后通过 typing.Pattern

    在实践中,这种设想从未真正实现:我怀疑这部分是因为pep484类型检查器的类型推理功能非常复杂,可以让您避免在很多情况下显式地提供类型提示,部分是因为直接将这些类型包含在 typing 或者在对应于相关标准库模块的存根中。

    https://github.com/python/typing/issues/589 和 https://github.com/python/cpython/pull/10173 键入.io 和 --新的建议是直接从 打字 而不是模块。

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