cuốn sách gpt4 ai đã làm

Tại sao dataclasses.astuple trả về bản sao sâu của thuộc tính lớp?

In lại Tác giả: Walker 123 更新时间:2023-11-28 17:04:40 25 4
mua khóa gpt4 Nike

在下面的代码中,astuple 函数正在对数据类的类属性进行深度复制。为什么它不会产生与函数 my_tuple 相同的结果?

import copy
import dataclasses


@dataclasses.dataclass
class Demo:
a_number: int
a_bool: bool
classy: 'YOhY'

def my_tuple(self):
return self.a_number, self.a_bool, self.classy

class YOhY:
def __repr__(self):
return (self.__class__.__qualname__ + f" id={id(self)}")


why = YOhY()
print(why) # YOhY id=4369078368

demo = Demo(1, True, why)
print(demo) # Demo(a_number=1, a_bool=True, classy=YOhY id=4369078368)

untrupled = demo.my_tuple()
print(untrupled) # YOhY id=4369078368

trupled = dataclasses.astuple(demo)
print(trupled) # YOhY id=4374460064

trupled2 = trupled
print(trupled2) # YOhY id=4374460064

trupled3 = copy.copy(trupled)
print(trupled3) # YOhY id=4374460064

trupled4 = copy.deepcopy(trupled)
print(trupled4) # YOhY id=4374460176

脚注

BẰNGAnthony Sottile's出色的响应清楚地表明这是编码到 Python 3.7 中的行为。任何希望 astuple 以与 collections.namedtuple 相同的方式解包的人都需要将其替换为类似于 Demo.my_tuple 的方法。下面的代码没有 my_tuple 那么脆弱,因为如果数据类的字段发生变化,它不需要修改。另一方面,如果 __slots__ 正在使用中,它将不起作用。

只要类或其父类(super class)中存在 __hash__ 方法,两个版本的代码都会构成威胁。请参阅有关 unsafe_hash 的 Python 3.7 文档,特别是开头的两段“这是管理 __hash__() 方法隐式创建的规则”。

def unsafe_astuple(self):
return tuple([self.__dict__[field.name] for field in dataclasses.fields(self)])

câu trả lời hay nhất

这似乎是一个 undocumented astuple 的行为(和 asdict 似乎也是如此)。

dataclasses.astuple(*, tuple_factory=tuple)

Converts the dataclass instance to a tuple (by using the factory function tuple_factory). Each dataclass is converted to a tuple of its field values. dataclasses, dicts, lists, and tuples are recursed into.

Đây là the source :

def _asdict_inner(obj, dict_factory):
if _is_dataclass_instance(obj):
result = []
for f in fields(obj):
value = _asdict_inner(getattr(obj, f.name), dict_factory)
result.append((f.name, value))
return dict_factory(result)
elif isinstance(obj, (list, tuple)):
return type(obj)(_asdict_inner(v, dict_factory) for v in obj)
elif isinstance(obj, dict):
return type(obj)((_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory))
for k, v in obj.items())
khác:
return copy.deepcopy(obj)

这里的 deepcopy 似乎是故意的,但可能应该记录在案。

关于python - 为什么 dataclasses.astuple 返回类属性的深度拷贝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51802109/

25 4 0
Walker 123
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress