一个(任意)Python模块的类型提示是什么?

50

我想为一个模块(类“module”)添加(Python3)类型提示。 typing 包没有提供这个,而 types.ModuleType() 是一个构造函数,它返回一个特定名称的模块对象。

例子:

import types
def foo(module: types.ModuleType):
   pass

在PyCharm中至少会导致

"types.pyi中找不到ModuleType的引用"。

请注意,关于Python模块类型的类型提示并不能回答我的问题,因为它没有解释ModuleType既是构造函数又是类型,如下所述。


已经修复 - user2235698
这个回答解决了你的问题吗?Python类型注释模块类型 - Georgy
@Gregory 不,它不会。 - TheDiveO
@TheDiveO,虽然它回答了标题中的问题。在我看来,标题应该更新以反映实际问题。我已经撤回了关闭投票。 - Georgy
1个回答

50
types.ModuleType()是一个构造函数。
这并不重要。types.ModuleType仍然是一个类型的引用,就像strint一样。在这里不需要一个通用的Module[typehint]注释,所以types.ModuleType正是你需要在这里使用的。
例如,官方的Python typeshed项目提供了一个sys.modules的类型提示注释,如下所示:
from types import FrameType, ModuleType, TracebackType

# ...

modules: Dict[str, ModuleType]

不要被这里的名字所迷惑;types.ModuleType是对模块类型的引用。它不是一个独立的工厂函数或其他什么东西。驼峰命名法遵循了该模块的约定,你使用该引用是因为类型对象在内置中不可用。types模块将type(sys)的值分配给该名称。
如果PyCharm在查找types.ModuleType的存根时出现问题,那么要么是PyCharm本身的问题(一个bug),要么是当前捆绑的存根已过时,要么是你使用了不完整的typeshed存根集。请参阅PyCharm文档中关于如何使用自定义存根的部分,以提供一个新鲜的集合。
如果这样不起作用,那可能是PyCharm中处理“导出”类型提示概念的一个错误。Typeshed目前在一个单独的模块中定义了ModuleType类型提示,然后使用“from module import name as name”语法将其导入到types.pyi存根文件中。根据PEP 484的规定,导入的类型提示不是存根的一部分,除非你使用“as”语法。
除非导入使用import ... as ...形式或等效的from ... import ... as ...形式,否则导入到存根中的模块和变量不被视为从存根中导出。
可能是PyCharm尚未正确处理这种情况。

1
这可能是PyCharm的代码检查问题吗? - TheDiveO
2
@TheDiveO:你展示的错误可能是PyCharm的一个bug或者是过时的本地存根文件,因为我可以看到ModuleType类型注释,它是从types.pyi中导出的。 - Martijn Pieters
这是一个与PyCharm版本和存根有关的问题;在切换到基于snap的最新PyCharm安装后,警告消失了,PyCharm现在正确地接受types.ModuleType。非常感谢您帮助澄清情况:我不知道typeshed基础设施。很遗憾,在提出严肃问题时会有那么多恶意投票。 - TheDiveO
7
@TheDiveO:投票很少,如果有的话,就不是“钓鱼”。我注意到在您添加有关PyCharm对使用typing.ModuleType的反应的信息后,您获得了赞成票,使得您的问题对其他访问者更有用。 Stack Overflow的目标是建立一个对其他人有帮助的问题存储库,并通过添加更多信息使其更有用。投票在这里用于指示其他人认为帖子对目标有多有用。另请参见[何时有理由对问题进行投票?](//meta.stackoverflow.com/q/252677) - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接