Bol*_*ain 12 python namedtuple
Python的namedtuple作为一个轻量级,不可变的数据类非常有用.我喜欢将它们用于簿记参数而不是字典.当需要更多功能时,例如简单的文档字符串或默认值,您可以轻松地将namedtuple重构为类.但是,我已经看到继承自namedtuple的类.他们获得了什么功能,他们失去了什么表现?例如,我会将其实现为
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__ = ()
Run Code Online (Sandbox Code Playgroud)
唯一的目的是能够干净地记录attrs,并__slots__用于防止创建__dict__(保持namedtuples的轻量级特性).
是否有更好的建议使用轻量级数据类来记录参数?注意我使用的是Python 2.7.
Ric*_*ica 15
新更新:
在python 3.6+中,您可以使用新的类型语法并创建一个typing.NamedTuple.新语法支持所有常见的python类创建功能(文档字符串,多重继承,默认参数,方法等等,从3.6.1开始提供):
import typing
class Pokemon(MyMixin, typing.NamedTuple):
"""
Attributes
----------
name : str
What do you call your Pokemon?
type : str
grass, rock, electric, etc.
level : int
Experience level [0, 100]
"""
name: str
type: str
level: int = 0 # 3.6.1 required for default args
def method(self):
# method work
Run Code Online (Sandbox Code Playgroud)
此版本创建的类的对象大多是相当于原来collections.namedtuple,除了几个细节.
您还可以使用与旧命名元组相同的语法:
Pokemon = typing.NamedTuple('Pokemon', [('name', str), ('type', str), ('level', int)])
Run Code Online (Sandbox Code Playgroud)
原始答案
在P3文档似乎相当明确暗示,除非你需要添加计算字段(即,描述符),子类namedtuple不被认为是规范的做法.这是因为您可以直接更新文档字符串(它们现在可以写为3.5!).
子类化对于添加新的存储字段没有用.相反,只需从
_fields属性中创建一个新的命名元组类型...可以通过直接分配
__doc__字段来自定义文档字符串...
更新:
现在,在最新版本的Python中,轻量级数据类还有其他一些令人信服的可能性.
一个是types.SimpleNamespace(Python 3.3及更高版本).它的结构不像namedtuple,但结构并不总是必要的.
有一点需要注意SimpleNamespace:默认情况下,在实例化类时需要显式指定字段名称.不过,这可以通过以下方式轻松解决super().__init__:
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)
Run Code Online (Sandbox Code Playgroud)
另一个有趣的选择 - 从Python 3.7(尚未发布)开始提供 - 是dataclasses.dataclass(参见PEP 557):
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]
Run Code Online (Sandbox Code Playgroud)
请注意,默认情况下,这两个建议都是可变的,__slots__任何一个都不需要.