在下面的代码中,astuple
函数正在执行dataclass的class属性的深层复制。为什么它不能产生与函数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
脚注
正如Anthony Sottile's出色的响应清楚地表明,这是编码到python3.7中的行为。任何人都希望astuples以同样的方式解包collections.namedtuple将需要用类似于Demo.my_tuple
的方法替换它。下面的代码没有我的元组脆弱,因为如果dataclass的字段被更改,则不需要修改它。另一方面,如果__slots__
正在使用,它将无法工作。在
每当__hash__
方法出现在类或其超类中时,这两个版本的代码都会造成威胁。关于unsafe_hash
,请参阅python3.7文档,尤其是以“这里是管理隐式创建__hash__()
方法的规则”开头的两段。在
这似乎是
astuple
的undocumented行为(看起来也是asdict
)。在这是the source:
这里的deepcopy似乎是有意为之,但可能应该记录在案。在
相关问题 更多 >
编程相关推荐