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

int子类__new__方法意外类型警告的原因及优化方案

问题解答

1. 警告产生的原因

PyCharm的静态类型检查是基于int.__new__的类型签名判断的。Python官方给int.__new__的类型注解里,第一个非类参数被标注为str | bytes | bytearray,但实际运行中int构造函数是支持接收int类型参数的(比如int(123)完全合法)。这种静态检查签名和实际运行逻辑的不一致,导致PyCharm抛出了类型不匹配的警告。

2. 为什么super(Size, cls).__new__ == int.__new__为True却提示不接受int?

虽然super(Size, cls).__new__确实指向int.__new__,但静态类型检查只认函数的类型注解签名,不管实际运行时的参数处理逻辑。int.__new__的类型注解只声明了接受字符串类类型,所以PyCharm会按这个签名做检查,哪怕实际运行时int.__new__能处理int参数。本质是静态检查和运行时逻辑“脱钩”了。

3. 创建支持多输入类型的int子类的更优方式

要实现像Size(1024)或Size('1 KiB')这样的多实例化方式,可按以下思路实现:

  • 重写__new__方法,先对输入参数做类型判断和转换:
    • 如果是int,直接保留或做数值处理
    • 如果是字符串,解析成对应的目标数值(比如处理'KiB'这类单位)
  • 用@overload标注不同的构造重载,让静态类型检查器识别合法的输入类型
  • 最后调用父类__new__时,确保传入的参数符合int.__new__的处理逻辑

示例代码:

from typing import overload, Union

class Size(int):
    @overload
    def __new__(cls, value: int) -> 'Size': ...
    @overload
    def __new__(cls, value: str) -> 'Size': ...
    
    def __new__(cls, value: Union[int, str]):
        if isinstance(value, str):
            # 解析带单位的字符串,比如'1 KiB'转为1024
            num_str, unit = value.strip().split()
            num = float(num_str)
            unit_map = {'KiB': 1024, 'MiB': 1024**2, 'GiB': 1024**3}
            value = int(num * unit_map[unit])
        # 将处理后的数值传给父类__new__
        return super().__new__(cls, value)

这样既实现了自定义实例化逻辑,又能让IDE识别合法输入类型,避免不必要的警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:52:40