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

Python中如何定义仅接受自定义类实例的类型MyType?

实现接受自定义类实例但拒绝内置类型的类型提示

要定义一个仅接受自定义类实例、拒绝内置类型(如int、list、dict)的类型MyType,可以利用Python的Protocol(协议类型)结合类的模块属性区分二者——内置类型的实例所属类的模块是builtins,而自定义类的模块通常是用户代码所在的模块(如__main__)。

解决方案代码

静态类型检查方案(适配mypy等工具)

from typing import Protocol

class CustomInstance(Protocol):
    """仅接受自定义类实例的协议类型"""
    __module__: str

def func(x: CustomInstance) -> None:
    pass

# 测试案例
func([])  # 类型检查器会报错:参数类型"list[Never]"与"CustomInstance"不兼容
func(5)   # 类型检查器会报错:参数类型"int"与"CustomInstance"不兼容

class Dog:
    pass

func(Dog())  # 无类型错误,符合要求

带运行时检查的增强方案

如果需要同时支持运行时类型验证,可以结合runtime_checkable和自定义检查逻辑:

from typing import Protocol, runtime_checkable

@runtime_checkable
class CustomInstance(Protocol):
    """带运行时检查的自定义实例协议"""
    @property
    def __module__(self) -> str:
        return self.__class__.__module__

def func(x: CustomInstance) -> None:
    # 运行时验证
    if x.__class__.__module__ == 'builtins':
        raise TypeError("仅接受自定义类实例")

# 测试案例
func([])  # 运行时抛出TypeError,类型检查器也会报错
func(5)   # 运行时抛出TypeError,类型检查器也会报错

class Dog:
    pass

func(Dog())  # 无错误

注意事项

  • 该方案基于类的模块归属判断:如果自定义类继承了内置类型(如class MyList(list): ...),其实例的模块是自定义模块,会被CustomInstance接受。若需要排除这类继承内置类型的自定义类,可以修改检查逻辑为self.__class__ not in vars(builtins).values()。
  • 依赖类型检查器对Protocol的支持(如mypy 0.780+)。

内容的提问来源于stack exchange,提问作者Garrett

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:01:01