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

含ctypes对象的dataclasses内存分配重叠问题咨询

问题原因解析

核心问题:类属性与实例属性的误用

你在dataclass中定义的x = ctypes.c_int(0)和y = ctypes.c_int(0)是类属性,而非实例属性。类属性绑定在类本身,所有该类的实例都会共享同一个类属性对象——而ctypes.c_int是可变对象,这就导致所有Point实例的x、y都指向同一块内存地址。

当你在TestObj中定义point1 = Point()和point2 = Point()时,这两个Point实例的x、y本质上是同一个ctypes.c_int(0)对象的引用。所以调用inc修改point1.x和point1.y时,point2的对应属性也会被修改——因为它们指向的是同一块内存。

为什么更换类名(Point2)就正常?

Point2是一个独立的类,它的x、y类属性属于Point2自己,和Point类的x、y是完全不同的ctypes.c_int对象。因此:

  • TestObj.point1(Point实例)共享Point类的x、y
  • TestObj.point2(Point2实例)共享Point2类的x、y
    这两组属性指向不同的内存地址,修改其中一组自然不会影响另一组。

正确的写法:使用实例属性

要让每个dataclass实例拥有独立的ctypes对象,需要定义实例属性,并通过default_factory为每个实例创建新的ctypes对象(直接赋值默认值会再次变成类级别的共享对象):

import dataclasses
import ctypes

@dataclasses.dataclass
class Point:
    x: ctypes.c_int = dataclasses.field(default_factory=lambda: ctypes.c_int(0))
    y: ctypes.c_int = dataclasses.field(default_factory=lambda: ctypes.c_int(0))

@dataclasses.dataclass
class TestObj:
    point1: Point = dataclasses.field(default_factory=Point)
    point2: Point = dataclasses.field(default_factory=Point)

这样每个Point实例都会生成自己独有的x、y对象,TestObj的point1和point2的属性就不会共享内存,调用inc后只会修改point1的属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 02:37:45