Python 使用类作为数据容器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3357581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:38:35  来源:igfitidea点击:

Using a class as a data container

pythonclassdictionarystruct

提问by gaefan

Sometimes it makes sense to cluster related data together. I tend to do so with a dict, e.g.,

有时将相关数据聚集在一起是有意义的。我倾向于使用 dict 这样做,例如,

self.group = dict(a=1, b=2, c=3)
print self.group['a']

One of my colleagues prefers to create a class

我的一个同事更喜欢创建一个类

class groupClass(object):
    def __init__(a, b, c):
        self.a = a
        self.b = b
        self.c = c
self.group = groupClass(1, 2, 3)
print self.group.a

Note that we are not defining any class methods.

请注意,我们没有定义任何类方法。

I like to use a dict because I like to minimize the number of lines of code. My colleague thinks the code is more readable if you use a class, and it makes it easier to add methods to the class in the future.

我喜欢使用字典,因为我喜欢尽量减少代码行数。我的同事认为如果使用类,代码可读性更好,并且以后可以更容易地向类中添加方法。

Which do you prefer and why?

你更偏向于哪个,为什么?

采纳答案by Joe Kington

If you're really never defining any class methods, a dict or a namedtuplemake far more sense, in my opinion. Simple+builtin is good! To each his own, though.

在我看来,如果您真的从未定义任何类方法,那么 dict 或namedtuple会更有意义。简单+内置很好!不过,对每个人来说。

回答by Ignacio Vazquez-Abrams

I prefer to follow YAGNIand use a dict.

我更喜欢遵循YAGNI并使用 dict。

回答by Brian S

In a language which supports it, I would use a struct. A dictionary would be closest to a structure in Python, at least as far as I see it.

在支持它的语言中,我会使用struct. 字典最接近 Python 中的结构,至少在我看来是这样。

Not to mention, you could add a method to a dictionary anyway if you reallywanted to ;)

更不用说,如果你真的想,你可以在字典中添加一个方法;)

回答by Vinko Vrsalovic

I disagree that the code is more readable using a class with no methods. You usually expect functionality from a class, not only data.

我不同意使用没有方法的类使代码更具可读性。您通常期望类的功能,而不仅仅是数据。

So, I'd go for a dict until the need for functionality arises, and then the constructor of the class could receive a dict :-)

因此,在需要功能之前,我会使用 dict,然后类的构造函数可以接收 dict :-)

回答by jeffcook2150

A dict is obviously appropriate for that situation. It was designed specifically for that use case. Unless you are actually going to use the class as a class, there's no use in reinventing the wheel and incurring the additional overhead / wasting the space of a class that acts as a bad dictionary (no dictionary features).

dict 显然适合这种情况。它是专门为该用例设计的。除非您实际上打算将类用作类,否则重新发明轮子并产生额外的开销/浪费用作坏字典(没有字典功能)的类的空间是没有用的。

回答by Muhammad Alkarouri

Your way is better. Don't try to anticipate the future too much as you are not likely to succeed.

你的方法更好。不要试图过多地预测未来,因为你不太可能成功。

However, it may make sense sometimes to use something like a C struct, for example if you want to identify different types rather than use dicts for everything.

但是,有时使用 C struct 之类的东西可能是有意义的,例如,如果您想识别不同的类型而不是对所有内容都使用 dicts。

回答by agdk26

You can combine advantages of dict and class together, using some wrapper class inherited from dict. You do not need to write boilerplate code, and at the same time can use dot notation.

您可以使用从 dict 继承的一些包装类,将 dict 和 class 的优点结合在一起。您不需要编写样板代码,同时可以使用点表示法。

class ObjDict(dict):
    def __getattr__(self,attr):
        return self[attr]
    def __setattr__(self,attr,value):
        self[attr]=value

self.group = ObjDict(a=1, b=2, c=3)
print self.group.a

回答by nesdis

There is a new proposal that aims to implement exactly what you are looking for, called data classes. Take a look at it.

有一个新提案旨在准确实现您正在寻找的内容,称为数据类。看一看。

Using a class over a dict is a matter of preference. Personally I prefer using a dict when the keys are not known a priori. (As a mapping container).

在 dict 上使用类是一个偏好问题。就个人而言,我更喜欢在先验不知道密钥时使用 dict。(作为映射容器)。

Using a class to hold data means you can provide documentation to the class attributes.

使用类来保存数据意味着您可以为类属性提供文档。

Personally, perhaps the biggest reason for me to use a class is to make use of the IDEs auto-complete feature! (technically a lame reason, but very useful in practise)

就个人而言,也许我使用类的最大原因是利用 IDE 的自动完成功能!(技术上是一个蹩脚的理由,但在实践中非常有用)

回答by pylang

Background

背景

A summary of alternative attribute-based, data containers was presented by R. Hettinger at the SF Python's 2017 Holiday meetup. See his tweetand his slide deck. He also gave a talkat PyCon 2018 on dataclasses.

R. Hettinger 在 SF Python 的 2017 年假日聚会上介绍了基于属性的替代数据容器的摘要。查看他的推文幻灯片。他还在PyCon 2018 上发表了关于数据类的演讲

Other data container types are mentioned in this articleand predominantly in Python 3 documentation (see links below).

本文中提到了其他数据容器类型,主要是在 Python 3 文档中(请参阅下面的链接)。

Here is a discussion on the python-ideasmailing list on adding recordclassto the standard library.

这是关于添加到标准库的python-ideas邮件列表的讨论recordclass

Options

选项

Alternatives in the Standard Library

标准库中的替代品

External options

外部选项

  • records: mutable namedtuple (see also recordclass)
  • bunch: add attribute access to dicts (inspiration for SimpleNamedspace; see also munch(py3))
  • box: wrap dicts with dot-style lookupfunctionality
  • attrdict: access elements from a mapping as keys or attributes
  • fields: remove boilerplate from container classes.
  • namedlist: mutable, tuple-like containers with defaults by E. Smith
  • misc.: posts on making your own custom struct, object, bunch, dict proxy, etc.
  • 记录:可变的命名元组(另见记录
  • :添加对dicts 的属性访问(灵感来源SimpleNamedspace;另见munch(py3))
  • box: 用点式查找功能包装 dicts
  • attrdict:从映射中访问元素作为键或属性
  • fields:从容器类中删除样板。
  • namedlist: 可变的、类似元组的容器,由 E. Smith 提供默认值
  • 杂项 :关于制作您自己的自定义结构、对象、束、字典代理等的帖子。

Which one?

哪一个?

Deciding which option to use depends on the situation (see Examples below). Usually an old fashioned mutable dictionary or immutable namedtuple is good enough. Data classes are the newest addition (Python 3.7a) offering both mutability and optional immutability, with promise of reduced boilerplate as inspired by the attrsproject.

决定使用哪个选项取决于具体情况(参见下面的示例)。通常老式的可变字典或不可变的 namedtuple 就足够了。数据类是最新添加的(Python 3.7a),提供可变性和可选的不变性,并承诺在attrs项目的启发下减少样板。



Examples

例子

import typing as typ
import collections as ct
import dataclasses as dc


# Problem: You want a simple container to hold personal data.
# Solution: Try a NamedTuple.
>>> class Person(typ.NamedTuple):
...     name: str
...     age: int
>>> a = Person("bob", 30)
>>> a
Person(name='bob', age=30)

# Problem: You need to change age each year, but namedtuples are immutable. 
# Solution: Use assignable attributes of a traditional class.
>>> class Person:
...     def __init__(self, name, age):
...         self.name = name
...         self.age = age
>>> b = Person("bob", 30)
>>> b.age = 31
>>> b
<__main__.Person at 0x4e27128>

# Problem: You lost the pretty repr and want to add comparison features.
# Solution: Use included repr and eq features from the new dataclasses.
>>> @dc.dataclass(eq=True)
... class Person:
...     name: str
...     age: int
>>> c = Person("bob", 30)
>>> c.age = 31
>>> c
Person(name='bob', age=31)
>>> d = Person("dan", 31)
>>> c != d
True

回答by Ramazan Polat

What about Prodict:

产品怎么

group = Prodict(a=1, b=2, c=3)
group.d = 4

And if you want auto type conversion and auto code complete(intelli-sense):

如果你想要自动类型转换和自动代码完成(智能感知):

class Person(Prodict):
    name: str
    email: str
    rate: int

john = Person(name='John', email='[email protected]')
john.rate = 7
john.age = 35  # dynamic