DataClass 是否适合替代字典?
Is DataClass a good fit to replace a dictionary?
我在代码中经常使用字典作为数据结构。而不是像 Python 那样返回多个值 Tuple
允许它:
def do_smth():
[...]
return val1, val2, val3
我更喜欢使用具有命名键的优点的字典。
但是对于复杂的嵌套字典,很难在其中导航。几年前当我用 JS 编码时,我也喜欢字典,因为我可以调用像 thing.stuff.foo
这样的子部分,而 IDE 帮助我构建了结构。
我刚刚在 python 中发现了新的 DataClass
,除了替换字典外,我不确定这是什么原因?对于我所读到的内容,DataClass
内部不能有函数,并且简化了其参数的初始化。
我想对此发表评论,你如何使用 DataClass
,或关于 python 中的字典。
我的看法。
A DataClass
不一定要替换字典。相反,它被用作一个对象来保存一些在应用程序建模中有意义的数据。
假设我们正在构建一个简单的地址簿。假设它只是存储一些数据,Person
class 可以是一个数据 class,其中包含 name
、phone_number
等字段。然后我们可以使用字典来创建 name
到 Person
的查找,以便我们可以按名称检索此数据 class。
from dataclasses import dataclass
@dataclass
class Person:
def __init__(self, name, address, phone_number):
self.name = name
self.address = address
self.phone_number = phone_number
然后在应用的其他地方:
persons = <LIST OF PERSONS>
address_book = {person.name: person for person in persons}
这是一个基本的例子,但我希望它能理解这个想法。
当然有人会争论为什么在 namedtuple
就足够的情况下使用 dataclass
?
其他人也写过关于该主题的文章:
去吧,纯 OO 是否可以拥有纯数据 classes 尤其是在处理多线程时。不过,我的建议是尝试仅在需要和使用的地方插入此信息(将数据 class 与功能混合)。
Data类 更像是 NamedTuples 的替代品,然后是字典。
虽然 NamedTuples 被设计为不可变的,但 data类 可以通过在装饰器中设置 frozen=True
来提供该功能,但总体上提供了更大的灵活性。
如果您在 Python 代码中使用 type hints,它们就会发挥作用。
另一个优点如您所说 - 复杂的嵌套字典。您可以将 Data类 定义为您的类型,并以清晰简洁的方式在 Data类 中表示它们。
考虑以下因素:
@dataclass
class City:
code: str
population: int
@dataclass
class Country:
code: str
currency: str
cities: List[City]
@dataclass
class Locations:
countries: List[Country]
然后您可以编写函数,在其中用数据类名称作为类型提示注释函数参数并访问它的属性(类似于传入字典并访问它的键),或者构造数据类并输出它,即
def get_locations(....) -> Locations:
....
它使代码非常可读,而不是一个大而复杂的字典。
您还可以设置默认值,这在 NamedTuples 中是不允许的,但在字典中是允许的。
@dataclass
class Stock:
quantity: int = 0
您还可以在装饰器中控制是否要对数据类进行排序等,就像是否要冻结它一样,而普通词典则不排序。 See here for more information
如果需要,您可以获得对象比较的所有好处,即 __eq__()
等。默认情况下,它们还带有 __init__
和 __repr__
,因此您无需键入像正常 类.
一样手动退出这些方法
对字段的控制也大大增加,允许使用元数据等。
最后,您可以通过导入 from dataclasses import dataclass asdict
将其转换为字典
我在代码中经常使用字典作为数据结构。而不是像 Python 那样返回多个值 Tuple
允许它:
def do_smth():
[...]
return val1, val2, val3
我更喜欢使用具有命名键的优点的字典。
但是对于复杂的嵌套字典,很难在其中导航。几年前当我用 JS 编码时,我也喜欢字典,因为我可以调用像 thing.stuff.foo
这样的子部分,而 IDE 帮助我构建了结构。
我刚刚在 python 中发现了新的 DataClass
,除了替换字典外,我不确定这是什么原因?对于我所读到的内容,DataClass
内部不能有函数,并且简化了其参数的初始化。
我想对此发表评论,你如何使用 DataClass
,或关于 python 中的字典。
我的看法。
A DataClass
不一定要替换字典。相反,它被用作一个对象来保存一些在应用程序建模中有意义的数据。
假设我们正在构建一个简单的地址簿。假设它只是存储一些数据,Person
class 可以是一个数据 class,其中包含 name
、phone_number
等字段。然后我们可以使用字典来创建 name
到 Person
的查找,以便我们可以按名称检索此数据 class。
from dataclasses import dataclass
@dataclass
class Person:
def __init__(self, name, address, phone_number):
self.name = name
self.address = address
self.phone_number = phone_number
然后在应用的其他地方:
persons = <LIST OF PERSONS>
address_book = {person.name: person for person in persons}
这是一个基本的例子,但我希望它能理解这个想法。
当然有人会争论为什么在 namedtuple
就足够的情况下使用 dataclass
?
其他人也写过关于该主题的文章:
去吧,纯 OO 是否可以拥有纯数据 classes 尤其是在处理多线程时。不过,我的建议是尝试仅在需要和使用的地方插入此信息(将数据 class 与功能混合)。
Data类 更像是 NamedTuples 的替代品,然后是字典。
虽然 NamedTuples 被设计为不可变的,但 data类 可以通过在装饰器中设置 frozen=True
来提供该功能,但总体上提供了更大的灵活性。
如果您在 Python 代码中使用 type hints,它们就会发挥作用。
另一个优点如您所说 - 复杂的嵌套字典。您可以将 Data类 定义为您的类型,并以清晰简洁的方式在 Data类 中表示它们。
考虑以下因素:
@dataclass
class City:
code: str
population: int
@dataclass
class Country:
code: str
currency: str
cities: List[City]
@dataclass
class Locations:
countries: List[Country]
然后您可以编写函数,在其中用数据类名称作为类型提示注释函数参数并访问它的属性(类似于传入字典并访问它的键),或者构造数据类并输出它,即
def get_locations(....) -> Locations:
....
它使代码非常可读,而不是一个大而复杂的字典。
您还可以设置默认值,这在 NamedTuples 中是不允许的,但在字典中是允许的。
@dataclass
class Stock:
quantity: int = 0
您还可以在装饰器中控制是否要对数据类进行排序等,就像是否要冻结它一样,而普通词典则不排序。 See here for more information
如果需要,您可以获得对象比较的所有好处,即 __eq__()
等。默认情况下,它们还带有 __init__
和 __repr__
,因此您无需键入像正常 类.
对字段的控制也大大增加,允许使用元数据等。
最后,您可以通过导入 from dataclasses import dataclass asdict