Python 中是否存在可变的命名元组?

新手上路,请多包涵

任何人都可以修改 namedtuple 或提供替代类以使其适用于可变对象吗?

主要是为了可读性,我想要类似于 namedtuple 的东西:

 from Camelot import namedgroup

Point = namedgroup('Point', ['x', 'y'])
p = Point(0, 0)
p.x = 10

>>> p
Point(x=10, y=0)

>>> p.x *= 10
Point(x=100, y=0)

必须可以腌制生成的对象。并且根据命名元组的特性,表示时输出的顺序必须与构造对象时参数列表的顺序相匹配。

原文由 Alexander 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 467
2 个回答

collections.namedtuple - recordclass 有一个可变的替代方案。它可以从 PyPI 安装:

 pip3 install recordclass

它具有与 namedtuple 相同的 API 和内存占用,并且它支持分配(它也应该更快)。例如:

 from recordclass import recordclass

Point = recordclass('Point', 'x y')

>>> p = Point(1, 2)
>>> p
Point(x=1, y=2)
>>> print(p.x, p.y)
1 2
>>> p.x += 2; p.y += 3; print(p)
Point(x=3, y=5)

recordclass (自0.5起)支持类型提示:

 from recordclass import recordclass, RecordClass

class Point(RecordClass):
   x: int
   y: int

>>> Point.__annotations__
{'x':int, 'y':int}
>>> p = Point(1, 2)
>>> p
Point(x=1, y=2)
>>> print(p.x, p.y)
1 2
>>> p.x += 2; p.y += 3; print(p)
Point(x=3, y=5)

有一个更完整的 示例(它还包括性能比较)。

Recordclass 库现在提供另一个变体 recordclass.make_dataclass 工厂函数。 It support dataclasses-like API (there are module level functions update , make , replace instead of self._update , self._replace , self._asdict , cls._make 方法)。

 from recordclass import dataobject, make_dataclass

Point = make_dataclass('Point', [('x', int), ('y',int)])
Point = make_dataclass('Point', {'x':int, 'y':int})

class Point(dataobject):
   x: int
   y: int

>>> p = Point(1, 2)
>>> p
Point(x=1, y=2)
>>> p.x = 10; p.y += 3; print(p)
Point(x=10, y=5)

recordclassmake_dataclass 可以生成类,其实例占用的内存少于基于 __slots__ 的实例。这对于具有属性值的实例可能很重要,这些实例不打算具有引用循环。如果您需要创建数百万个实例,它可能有助于减少内存使用量。这是一个说明性的 例子

原文由 intellimath 发布,翻译遵循 CC BY-SA 4.0 许可协议

作为此任务的 Pythonic 替代方案,自 Python-3.7 起,您可以使用 dataclasses 模块,它不仅表现得像一个可变的 NamedTuple ,因为它们使用普通类定义,它们还支持其他阶级特征。

来自 PEP-0557:

尽管它们使用非常不同的机制,但数据类可以被认为是“具有默认值的可变命名元组”。因为数据类使用普通的类定义语法,所以您可以自由使用继承、元类、文档字符串、用户定义的方法、类工厂和其他 Python 类功能。

提供了一个类装饰器,它使用 PEP 526 中定义的类型注释检查变量的类定义,“变量注释的语法”。在本文档中,此类变量称为字段。使用这些字段,装饰器将生成的方法定义添加到类中以支持实例初始化、repr、比较方法以及可选的其他方法,如 规范 部分中所述。这样的类称为数据类,但该类实际上没有什么特别之处:装饰器将生成的方法添加到类中并返回给定的相同类。

此功能在 PEP-0557 中引入,您可以在提供的文档链接上阅读更多详细信息。

例子:

 In [20]: from dataclasses import dataclass

In [21]: @dataclass
    ...: class InventoryItem:
    ...:     '''Class for keeping track of an item in inventory.'''
    ...:     name: str
    ...:     unit_price: float
    ...:     quantity_on_hand: int = 0
    ...:
    ...:     def total_cost(self) -> float:
    ...:         return self.unit_price * self.quantity_on_hand
    ...:

演示:

 In [23]: II = InventoryItem('bisc', 2000)

In [24]: II
Out[24]: InventoryItem(name='bisc', unit_price=2000, quantity_on_hand=0)

In [25]: II.name = 'choco'

In [26]: II.name
Out[26]: 'choco'

In [27]:

In [27]: II.unit_price *= 3

In [28]: II.unit_price
Out[28]: 6000

In [29]: II
Out[29]: InventoryItem(name='choco', unit_price=6000, quantity_on_hand=0)

原文由 Mazdak 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题