数据类引用同一个对象而不是初始化一个新对象
dataclass references the same object rather than initializing a new one
我有一个看起来像这样的数据类(经过简化和重命名):
@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()
但再次查看 dataclass docs 它实际上给了我这样的信息:
class SharedReference:
def __init__(self, bytes_io = BytesIO()):
self.bytes_io = bytes_io
其中 BytesIO()
在定义函数时执行,而不是在创建实例时执行。
field
的 default_factory
论点也解决了这个问题,并将努力将事情分开(其他人提到了这个但随后删除了他们的回答):
@dataclass
class SeparateReference:
bytes_io: BytesIO = field(default_factory=BytesIO)
我有一个看起来像这样的数据类(经过简化和重命名):
@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()
但再次查看 dataclass docs 它实际上给了我这样的信息:
class SharedReference:
def __init__(self, bytes_io = BytesIO()):
self.bytes_io = bytes_io
其中 BytesIO()
在定义函数时执行,而不是在创建实例时执行。
field
的 default_factory
论点也解决了这个问题,并将努力将事情分开(其他人提到了这个但随后删除了他们的回答):
@dataclass
class SeparateReference:
bytes_io: BytesIO = field(default_factory=BytesIO)