You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用importlib创建的模块对应的mypy类型是什么?

类型标注方案

通用场景标注

所有Python模块对象的标准类型是types.ModuleType,这是mypy官方认可的模块类型,通用场景下直接使用该类型标注返回值即可,修改后的完整代码如下:

from importlib.machinery import SourceFileLoader
from importlib.util import spec_from_loader, module_from_spec
from pathlib import Path
from typing import Union
from types import ModuleType

PathStr = Union[Path, str]

def load_module(module_path: PathStr, module_name: str = "module") -> ModuleType:
    """Load and return a module"""
    # 注意SourceFileLoader要求路径为字符串,此处主动转换避免mypy报错
    loader = SourceFileLoader(module_name, str(module_path))
    spec = spec_from_loader(loader.name, loader)
    module = module_from_spec(spec)
    loader.exec_module(module)
    return module

进阶:自定义模块结构的精确标注

如果你提前知道待加载模块的成员结构,想要获得更严格的类型检查,可以使用Protocol定义模块的结构契约,用自定义的Protocol作为返回类型,示例如下:

from typing import Protocol, Union
from pathlib import Path
from importlib.machinery import SourceFileLoader
from importlib.util import spec_from_loader, module_from_spec
# Python 3.8以下版本需从typing_extensions导入Protocol
# from typing_extensions import Protocol

PathStr = Union[Path, str]

# 定义你预期模块包含的属性和方法
class MyExpectedModule(Protocol):
    VERSION: str
    def run_task(self, param: int) -> bool: ...

def load_module(module_path: PathStr, module_name: str = "module") -> MyExpectedModule:
    loader = SourceFileLoader(module_name, str(module_path))
    spec = spec_from_loader(loader.name, loader)
    module = module_from_spec(spec)
    loader.exec_module(module)
    return module

使用该方案后,你调用返回模块的属性或方法时,mypy会自动做类型校验。

注意事项

  • 动态加载的模块mypy无法静态校验实际结构和你定义的Protocol是否匹配,需要你自行保证加载的模块符合约定结构
  • Python 3.8以下版本使用Protocol需要提前安装依赖:pip install typing-extensions

内容的提问来源于stack exchange,提问作者Jean-Francois T.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 12:36:01