这是皮林特盲法的另一个例子。
“类不是用来存储数据的”——这是一个错误的陈述。字典并不适合所有事情。类的数据成员是有意义的,字典项是可选的。证明:你可以做dictionary.get('key', DEFAULT_VALUE)来防止KeyError,但没有简单的__getattr__默认。
推荐的结构体使用方法
我需要更新我的答案。现在 - 如果您需要 struct,您有两个不错的选择:
a) 只需使用attrs
这是一个库:
https://www.attrs.org/en/stable/
import attr
@attr.s
class MyClass(object): # Or just MyClass: for Python 3
foo = attr.ib()
bar = attr.ib()
你会得到额外的东西:不编写构造函数、默认值、验证、__repr__、只读对象(替换 namedtuples,即使在 Python 2 中也是如此)等等。
b) 使用dataclasses (Py 3.7+)
根据hwjp的评论,我也推荐dataclasses:
https://docs.python.org/3/library/dataclasses.html
这几乎和attrs 一样好,并且是标准库机制(“包括电池”),没有额外的依赖项,除了 Python 3.7+。
上一个答案的其余部分
NamedTuple 不是很好——尤其是在 Python 3 的typing.NamedTuple 之前:
https://docs.python.org/3/library/typing.html#typing.NamedTuple
- 您绝对应该查看“派生自
NamedTuple 的类”模式。
Python 2 - namedtuples 从字符串描述创建 - 丑陋、糟糕并且“在字符串文字中编程”很愚蠢。
我同意当前的两个答案(“考虑使用其他东西,但 Pylint 并不总是正确的” - 已接受的答案和“使用 Pylint 抑制评论”),但我有自己的建议。
让我再次指出这一点:有些类只是用于存储数据。
现在也可以选择考虑 - 使用property-ies。
class MyClass(object):
def __init__(self, foo, bar):
self._foo = foo
self._bar = bar
@property
def foo(self):
return self._foo
@property
def bar(self):
return self._bar
上面你有只读属性,这对于值对象是可以的(例如,像领域驱动设计中的那些),但你也可以提供设置器 - 这样你的类将能够对你的字段负责有 - 例如做一些验证等(如果你有设置器,你可以在构造函数中使用它们进行分配,即self.foo = foo而不是直接self._foo = foo,但要小心,设置器可能假设其他字段已经初始化,然后您需要在构造函数中进行自定义验证)。