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

使用functools.singledispatch时遇AttributeError:'function'无'register'属性

问题解决方法

错误原因分析

  1. AttributeError 根源:注册实现时使用了和基础函数同名的my_func,直接覆盖了@singledispatch创建的调度对象(该对象带有register属性)。后续执行@my_func.register(list)时,my_func已经变成普通函数,自然没有register属性。
  2. Typeguard警告根源:基础函数的参数未添加类型注解,导致typeguard无法执行类型检查,抛出警告。

修正后的代码

from functools import singledispatch
from typeguard import typechecked
from typing import Union, Any


@singledispatch
@typechecked
def my_func(x: Any, y: Any) -> Union[int, str]:
    raise NotImplementedError(f'{type(x)} and/or {type(y)} are not supported.')


@my_func.register(int)
@typechecked
def _my_func_int(x: int, y: int) -> Union[int, str]:
    try:
        return round(100 * x / (x + y))
    except (ZeroDivisionError, TypeError, AssertionError) as e:
        return f'{e}'


@my_func.register(list)
@typechecked
def _my_func_list(x: list, y: list) -> Union[int, str]:
    try:
        return round(100 * sum(x) / (sum(x) + sum(y)))
    except (ZeroDivisionError, TypeError, AssertionError) as e:
        return f'{e}'


# 测试用例
a = my_func(1, 2)
print(a)  # 输出: 33

b = my_func([0, 1], [2, 3])
print(b)  # 输出: 17

# 测试混合类型(触发基础函数逻辑)
try:
    c = my_func(1, [2, 3])
    print(c)
except NotImplementedError as e:
    print(e)  # 输出: <class 'int'> and/or <class 'list'> are not supported.

关键修复点

  • 避免重名覆盖:给每个注册的实现函数使用独立名称(如_my_func_int、_my_func_list),保留@singledispatch创建的调度对象。
  • 添加类型注解:给基础函数参数添加Any类型注解,消除typeguard的警告;注册函数的类型注解确保参数类型符合预期。
  • 装饰器顺序:保持@singledispatch为最外层装饰器,确保调度对象的register属性可用;每个实现函数也添加@typechecked,维持类型检查逻辑。
  • 可选:多参数一致性检查:如果需要严格保证两个参数类型一致,可以在注册函数中添加额外检查,例如在_my_func_int中判断isinstance(y, int),不符合则调用基础函数逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 17:01:09