- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 Python 3.6 和来自 ericvsmith 的 dataclasses
backport 包.
似乎调用 dataclasses.asdict(my_dataclass)
比调用 my_dataclass.__dict__
慢 10 倍:
In [172]: @dataclass
...: class MyDataClass:
...: a: int
...: b: int
...: c: str
...:
In [173]: %%time
...: _ = [MyDataClass(1, 2, "A" * 1000).__dict__ for _ in range(1_000_000)]
...:
CPU times: user 631 ms, sys: 249 ms, total: 880 ms
Wall time: 880 ms
In [175]: %%time
...: _ = [dataclasses.asdict(MyDataClass(1, 2, "A" * 1000)) for _ in range(1_000_000)]
...:
CPU times: user 11.3 s, sys: 328 ms, total: 11.6 s
Wall time: 11.7 s
这是预期的行为吗?在什么情况下我必须使用 dataclasses.asdict(obj)
而不是 obj.__dict__
?
编辑:使用 __dict__.copy()
没有太大区别:
In [176]: %%time
...: _ = [MyDataClass(1, 2, "A" * 1000).__dict__.copy() for _ in range(1_000_000)]
...:
CPU times: user 922 ms, sys: 48 ms, total: 970 ms
Wall time: 970 ms
最佳答案
在大多数情况下你会使用 __dict__
而没有 dataclasses
,你可能应该继续使用 __dict__
,也许有一个 copy
调用。 asdict
做了很多您可能并不真正想要的额外工作。这是它的作用。
首先,来自docs :
Each dataclass is converted to a dict of its fields, as name: value pairs. dataclasses, dicts, lists, and tuples are recursed into. For example:
@dataclass
class Point:
x: int
y: int
@dataclass
class C:
mylist: List[Point]
p = Point(10, 20)
assert asdict(p) == {'x': 10, 'y': 20}
c = C([Point(0, 0), Point(10, 4)])
assert asdict(c) == {'mylist': [{'x': 0, 'y': 0}, {'x': 10, 'y': 4}]}
因此,如果您想要递归数据类听写,请使用 asdict
。如果您不想要它,那么提供它的所有开销都被浪费了。特别是,如果您使用 asdict
,则将包含对象的实现更改为使用 dataclass
将更改 asdict
对外部对象的结果。
递归逻辑也没有处理循环引用。如果您使用数据类来表示图形或任何其他具有循环引用的数据结构,asdict
将会崩溃:
import dataclasses
@dataclasses.dataclass
class GraphNode:
name: str
neighbors: list['GraphNode']
x = GraphNode('x', [])
y = GraphNode('y', [])
x.neighbors.append(y)
y.neighbors.append(x)
dataclasses.asdict(x) # crash here!
此示例中的 asdict
调用遇到了 RecursionError: maximum recursion depth exceeded while calling a Python object
。
除此之外,asdict
构建一个新 字典,而__dict__
只是直接访问对象的属性字典。 asdict
的返回值不会受到原始对象字段重新分配的影响。此外,asdict
使用 fields
,因此如果您将属性添加到与声明的字段不对应的数据类实例,asdict
将不会包含他们。
最后,文档根本没有提到它,但是 asdict
会 call deepcopy
在不是数据类对象、字典、列表或元组的所有内容上:
else:
return copy.deepcopy(obj)
(数据类对象、字典、列表和元组通过递归逻辑,它也构建一个副本,只是应用了递归听写。)
deepcopy
本身非常昂贵,并且缺少任何 memo
处理意味着 asdict
可能会创建共享的多个副本非平凡对象图中的对象。当心:
>>> from dataclasses import dataclass, asdict
>>> @dataclass
... class Foo:
... x: object
... y: object
...
>>> a = object()
>>> b = Foo(a, a)
>>> c = asdict(b)
>>> b.x is b.y
True
>>> c['x'] is c['y']
False
>>> c['x'] is b.x
False
关于python - 为什么 `dataclasses.asdict(obj)` > 10x 比 `obj.__dict__()` 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52229521/
c1 和c2 的构造函数中的默认值应该为b 和b 生成新的实例变量。相反,它看起来像 c1.a 和 c2.a 引用了同一个变量。 @dataclass 是否正在创建类变量?这似乎与预期的功能不一致,而
这个问题已经有答案了: C# - Cannot implicitly convert type List to List (6 个回答) Why does this generic cast fail
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 去年关闭。 Improve th
如何让它在 @dataclass 修饰的 Python 类中设置拼写错误的字段时引发异常? 我想要一个实用的方法来做到这一点。我是否需要改为编写自己的装饰器? @dataclass class C(o
Field 的文档python 标准类 dataclasses模块仅指定: Its documented attributes are: [...] type: The type of the fie
我正在尝试比较从公共(public)基类(也是@dataclass)继承的两个数据类。 继承类的字段是自己特有的,比较时不考虑;我只想比较基类属性。 这是我的尝试: from dataclasses
我试图在整个应用程序中使用整数和文本。我是通过使用 DataClass 来这样做的,并且我已经得到了可以工作的整数。但是,我不确定如何使用文本。我很确定使用 UILabel 是不正确的。我将在下面向您
我正在使用来自 dataclasses 的 dataclass 和 asdict ,我发现 asdict 并不像我在引入继承时所期望的那样工作。 我使用 dataclasses 来帮助我从类创建字典,
Python 3.7 引入了包含 @dataclass 装饰器的 dataclasses 模块。这个装饰器可以生成类函数。如何打印这些生成的函数? 最佳答案 我自己也问过同样的问题。 Dataclas
我有一堆@dataclass es 和一堆对应的 TypedDict s,我想促进它们之间的平滑和类型检查转换。 例如,考虑 from dataclasses import dataclass fro
我已经使用 highchart 绘制了一个热图,但我想为 y 轴提供颜色范围,即数据数组中的第二个索引,但它会自动采用第三个索引。 下面是jsfiddle代码。 Links for my code
Python 3.7 引入 dataclasses来存储数据。我正在考虑采用这种新方法,这种方法比字典更有条理,结构更合理。 但我有一个疑问。 Python 将键转换为 dicts 上的哈希,这使得查
在下面的代码中,astuple 函数正在对数据类的类属性进行深度复制。为什么它不会产生与函数 my_tuple 相同的结果? import copy import dataclasses @datac
总结 我有一个包含 10 多个字段 的数据类。 print()将它们隐藏在默认值墙中的有趣上下文 - 让我们通过避免不必要地重复这些来使它们更友好。 Python 中的数据类 Python 的 @da
我有一个数据类,它看起来像这样: @dataclass class myClass: id: str mode: str value: float 这导致: dataclasses.
我有一个类,我们称它为 Builder。它有一个私有(private)成员声明为 vector> buffers; // Node is a pure data class. 在这个 Builder
Python 3.7 提供了新的 dataclasses,它们具有预定义的特殊功能。 从总体上看,dataclasses 和 SimpleNamespace 都提供了很好的数据封装工具。 @datac
我试图在我的单元测试中使用 freezegun 来修补数据类中的一个字段,该字段设置为对象初始化时的当前日期。我想这个问题与任何尝试修补一个在 freezegun 之外用作 default_facto
我想使 set 参数可选,但仍允许 None 为有效值。基于the documentation , 它建议 dataclasses.MISSING 可以使用默认值来帮助实现这一点。 As shown
我想使 set 参数可选,但仍允许 None 为有效值。基于the documentation , 它建议 dataclasses.MISSING 可以使用默认值来帮助实现这一点。 As shown
我是一名优秀的程序员,十分优秀!