Python 子类化名为tuple的集合
Python的namedtuple作为一个轻量级的、不可变的数据类非常有用。我喜欢将它们用于记账参数,而不是字典。当需要更多功能时,例如简单的docstring或默认值,您可以轻松地将namedtuple重构为类。但是,我见过从namedtuple继承的类。它们获得了哪些功能,失去了哪些性能?例如,我会将其实现为Python 子类化名为tuple的集合,python,namedtuple,Python,Namedtuple,Python的namedtuple作为一个轻量级的、不可变的数据类非常有用。我喜欢将它们用于记账参数,而不是字典。当需要更多功能时,例如简单的docstring或默认值,您可以轻松地将namedtuple重构为类。但是,我见过从namedtuple继承的类。它们获得了哪些功能,失去了哪些性能?例如,我会将其实现为 from collections import namedtuple class Pokemon(namedtuple('Pokemon', 'name type level')):
from collections import namedtuple
class Pokemon(namedtuple('Pokemon', 'name type level')):
"""
Attributes
----------
name : str
What do you call your Pokemon?
type : str
grass, rock, electric, etc.
level : int
Experience level [0, 100]
"""
__slots__ = ()
唯一的目的是能够干净地记录属性,\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
用于防止创建\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
有没有更好的建议使用轻量级数据类来记录参数?注意,我使用的是Python 2.7。新更新:
在Python3.6+中,可以使用新的类型化语法并创建typing.NamedTuple
。新语法支持所有常见的python类创建功能(DocString、多重继承、默认参数、方法等从3.6.1开始提供):
此版本创建的类对象大部分相当于原始的集合。namedtuple
您还可以使用与旧命名元组相同的语法:
Pokemon = typing.NamedTuple('Pokemon', [('name', str), ('type', str), ('level', int)])
原始答案
简短回答:似乎相当清楚地表明,除非您需要添加计算字段(即描述符),否则子类化namedtuple
不被视为规范方法。这是因为您可以直接更新docstring(从3.5开始,它们现在是可写的!)
子类化对于添加新的存储字段没有用处。相反,只需从\u fields
属性创建一个新的命名元组类型
可以通过直接分配到\uuuu doc\uuu
字段来自定义文档字符串
更新:
现在,在最新版本的Python中,轻量级数据类还有一些其他令人信服的可能性
一个是。它的结构不像namedtuple
,但结构并不总是必需的
关于SimpleNamespace
,需要注意的一点是:在实例化类时,默认情况下需要显式指定字段名。不过,只要调用super(),就可以很容易地实现这一点
from types import SimpleNamespace
class Pokemon(SimpleNamespace):
"""
Attributes
----------
name : str
What do you call your Pokemon?
type : str
grass, rock, electric, etc.
level : int
Experience level [0, 100]
"""
__slots__ = ("name", "type", "level")
# note that use of __init__ is optional
def __init__(self, name, type, level):
super().__init__(name=name, type=type, level=level)
另一个有趣的选择是(另见):
请注意,这两个建议在默认情况下都是可变的,并且这两个建议都不需要\uuuuu\uuuuu
。另请参见关于替代数据容器(即NamedTuple
和数据类)的文章。在对NamedTuple旁边的任何类进行子类化时,其他类都将被忽略。因此,在第一个示例中,Pokemon
无法使用MyMixin
中声明的方法,您可以在此处查看我的问题以了解更多信息:
from types import SimpleNamespace
class Pokemon(SimpleNamespace):
"""
Attributes
----------
name : str
What do you call your Pokemon?
type : str
grass, rock, electric, etc.
level : int
Experience level [0, 100]
"""
__slots__ = ("name", "type", "level")
# note that use of __init__ is optional
def __init__(self, name, type, level):
super().__init__(name=name, type=type, level=level)
from dataclasses import dataclass
@dataclass
class Pokemon:
__slots__ = ("name", "type", "level")
name: str # What do you call your Pokemon?
type: str # grass, rock, electric, etc.
level: int = 0 # Experience level [0, 100]