dataclass引用同一个对象,而不是初始化一个新对象



我有一个数据类,看起来像这样(简化并重命名(:

@dataclass
class SharedReference:
bytes_io: BytesIO = BytesIO()

我遇到了一个问题,我不小心创建了一个共享引用,所以关闭一个实例的IO流会关闭所有实例。

查看id,我发现它引用了相同的内存id:

shared = SharedReference()
print(shared.bytes_io)  # 0x7f...5e0
shared.bytes_io.close()
shared_2 = SharedReference() 
print(shared_2.bytes_io)  # 0x7f...5e0 (same id)
print(shared_2.bytes_io.closed) # True (got accidentally closed)

但是这个数据类:

@dataclass
class SeparateReference:
bytes_io: BytesIO = field(init=False)
def __post_init__(self):
self.bytes_io = BytesIO()

工作正常:

separate = SeparateReference()
print(separate.bytes_io)  # 0x7f...d10
separate.bytes_io.close()
separate = SeparateReference() 
print(separate.bytes_io)  # 0x7f...680 (different id)
print(separate.bytes_io.closed)  # False (didn't get accidentally closed)

为什么第二个有效而第一个无效?

我认为我的第一个示例等效于以下代码:

class SeparateReference:
def __init__(self):
self.bytes_io = BytesIO()

但再看看数据类文档,它实际上给了我一些东西,比如:

class SharedReference:
def __init__(self, bytes_io = BytesIO()):
self.bytes_io = bytes_io

其中CCD_ 1在函数定义时而不是在创建实例时执行。

fielddefault_factory论点也解决了这一问题,并将努力将事情分开(其他人提到了这一点,但随后删除了他们的答案(:

@dataclass
class SeparateReference:
bytes_io: BytesIO = field(default_factory=BytesIO)

最新更新