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

Python中类型注解为何出现<class 'float'>与'float'两种形式?

抽象基类与实现类类型注解差异问题解析

问题场景

对比抽象基类与实现类的类型注解时,使用inspect.getfullargspec()工具获取参数注解,发现二者存在明显差异:

示例代码

抽象基类与实现类代码:

import abc
from typing import List, Tuple


class Abstract(abc.ABC):
    @abc.abstractmethod
    def get_hscodes(self, *, confidence_threshold: float = 0.0, **kwargs):
        pass


class Concrete(Abstract):
    def get_hscodes(self, *, confidence_threshold: float = 0.0, **kwargs):
        likely = self.get_likely_hscodes(confidence_threshold=confidence_threshold, **kwargs)
        return [i[0] if i else (None, 0.0) for i in likely]

    def get_likely_hscodes(
        self, *, confidence_threshold: float = 0.0, **kwargs
    ) -> List[List[Tuple]]:
        pass

执行检查代码:

import inspect

print(inspect.getfullargspec(Abstract.get_hscodes))
print(inspect.getfullargspec(Concrete.get_hscodes))

结果差异

  • 抽象基类方法Abstract.get_hscodes的注解:{'confidence_threshold': <class 'float'>}
  • 实现类方法Concrete.get_hscodes的注解:{'confidence_threshold': 'float'}

测试环境为Python 3.8.13(Windows、Linux均出现该情况),且该问题难以稳定复现。

差异原因

  1. abc.abstractmethod装饰器的处理逻辑
    当方法被@abc.abstractmethod装饰时,装饰器会直接保留原始的类型注解对象(即实际的float类),不会对注解做字符串化处理。抽象方法的装饰逻辑更注重保留方法的原始元信息,因此注解以类型对象形式存储。

  2. Python 3.8的类型注解延迟解析机制
    Python 3.8支持PEP 484定义的字符串形式类型注解(延迟评估),如果实现类的方法在加载或执行过程中,没有触发注解的解析逻辑(比如未调用typing.get_type_hints()、没有类型检查工具主动解析),注解就会以字符串'float'的形式保留。而普通方法没有像抽象方法那样的特殊元信息处理,更容易保留字符串形式的注解。

  3. 不稳定复现的诱因
    该问题难以稳定复现,是因为触发注解解析的场景具有随机性:

    • 代码加载顺序不同,可能导致某些模块提前触发了注解解析;
    • IDE后台类型检查、自动化测试工具、第三方依赖库可能会隐式调用注解解析逻辑,将字符串形式的注解转换为类型对象;
    • 不同环境下的模块缓存机制(如.pyc文件)也会影响注解的存储形式。

另外,Python 3.9及以上版本对类型注解的处理机制做了优化,inspect模块获取注解的逻辑更统一,这类不一致的情况会大幅减少。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 13:31:08