Python namedtuple使用详解

本文深入探讨了Python中collections模块的namedtuple特性,介绍了如何定义和使用namedtuple,以及它相对于普通tuple的优势,包括属性访问和转换为字典等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@author StormMa
@date 2017-06-12


生命不息,奋斗不止!


Python的collections模块在基础数据类型的基础上,提供了几个额外的数据类型:namedtuple, defaultdict, deque, Counter, OrderedDict等,其中defaultdict和namedtuple是两个很实用的扩展类型。我一贯的风格就是学一个数据类型,就想去看看源码,虽然看不太懂,但是总比不看的强,之前java的集合源码阅读也是基于这样一个目的。今天就从使用和源码的角度来看一下namedtuple。

namedtuple是继承自tuple的子类。namedtuple创建一个和tuple类似的对象,而且对象拥有可访问的属性。

定义namedtuple

类的声明

class NamedTuple(tuple):
    _fields = ...  # type: Tuple[str, ...]

    def __init__(self, typename: str, fields: Iterable[Tuple[str, Any]], *,
                 verbose: bool = ..., rename: bool = ..., module: Any = ...) -> None: ...

    @classmethod
    def _make(cls, iterable: Iterable[Any]) -> NamedTuple: ...

    def _asdict(self) -> dict: ...
    def _replace(self, **kwargs: Any) -> NamedTuple: ...

定义一个namedtuple的User类型

User = collections.namedtuple('User', ['age', 'name'])
或者
User = collections.namedtuple('User', 'age, name')
或者
User = collections.namedtuple('User', 'age name')

对应源码

def namedtuple(typename, field_names, verbose=False, rename=False):
    """Returns a new subclass of tuple with named fields.

    >>> Point = namedtuple('Point', ['x', 'y'])
    >>> Point.__doc__                   # docstring for the new class
    'Point(x, y)'
    >>> p = Point(11, y=22)             # instantiate with positional args or keywords
    >>> p[0] + p[1]                     # indexable like a plain tuple
    33
    >>> x, y = p                        # unpack like a regular tuple
    >>> x, y
    (11, 22)
    >>> p.x + p.y                       # fields also accessable by name
    33
    >>> d = p._asdict()                 # convert to a dictionary
    >>> d['x']
    11
    >>> Point(**d)                      # convert from a dictionary
    Point(x=11, y=22)
    >>> p._replace(x=100)               # _replace() is like str.replace() but targets named fields
    Point(x=100, y=22)

    """

    # Validate the field names.  At the user's option, either generate an error
    # message or automatically replace the field name with a valid name.
    if isinstance(field_names, str):
        field_names = field_names.replace(',', ' ').split()
    field_names = list(map(str, field_names))
创建对象
user = User = (21, 'StormMa')
或者
user = User(age=21, name='StormMa')
或者
user = User._make([21, 'name']) 
属性访问
# 年龄
user.age

# 姓名
user.name
转换成字典
user_dict = user._asdict()

# 访问 
user_dict['name']
user_dict['age']
替换属性值
user2 = user._replace(age=20)

本文来自我的个人站点: http://blog.stormma.me,转载请注明出处!

### Python 中结构体的详细用法和实现方式 尽管 Python 并未像 C/C++ 那样提供原生的 `struct` 关键字用于定义结构体,但它可以通过多种方式实现类似的结构化数据存储功能。以下是几种常见的替代方案及其详细说明: #### 1. 使用类 (`class`) 定义结构体 Python 的类可以用来模拟结构体的行为。通过自定义类并利用其构造函数 `__init__()` 初始化成员变量,能够轻松构建类似于结构体的对象。 ```python class Person: def __init__(self, name, age, address): self.name = name self.age = age self.address = address person = Person("Alice", 30, "New York") # 创建一个对象 print(person.name) # 输出 Alice ``` 这种方式的优点在于灵活性高,支持复杂逻辑处理以及继承等功能[^3]。 --- #### 2. 使用 `namedtuple` 构建不可变结构体 对于简单的场景,如果只需要固定字段而无需额外方法或可变状态,则推荐使用 `collections.namedtuple` 来快速创建轻量级的结构体。 ```python from collections import namedtuple Person = namedtuple('Person', ['name', 'age', 'address']) person = Person(name="Bob", age=25, address="Los Angeles") print(person.name) # 输出 Bob ``` `namedtuple` 提供了更高的性能表现,并且由于它是不可变的,在某些特定应用场合下更加安全可靠[^6]。 --- #### 3. 利用 `dataclasses` 模块简化结构体定义 (Python 3.7+) 从 Python 3.7 开始引入的 `dataclasses` 模块进一步降低了编写数据承载类的成本。只需标注字段即可自动获得默认行为(如比较运算符重载),非常适合代替传统意义上的 “结构体”。 ```python from dataclasses import dataclass @dataclass class Car: make: str model: str year: int car = Car(make="Toyota", model="Corolla", year=2020) print(car.make) # 输出 Toyota ``` 此方法不仅保持简洁明了,而且兼容性强,适合现代开发需求[^7]。 --- #### 4. 数组形式表示多个同类型结构体实例 当需要管理一组具有相同布局的数据记录时,可以直接采用列表或其他容器类型保存前述任一类型的对象集合。 ```python people = [ Person("Charlie", 35, "Chicago"), Person("Diana", 28, "Houston") ] for p in people: print(f"{p.name} lives in {p.address}.") ``` 这种做法本质上就是所谓的“结构体数组”,即每个元素均为独立完整的实体单位[^1]。 --- #### 注意事项 - **内存分配**:与低级语言不同的是,Python 对象由解释器负责动态管理和释放资源,因此开发者不必显式关心底层细节诸如指针操作或者手动调整偏移等问题[^4]。 - **字节对齐优化**:虽然理论上存在类似的概念,但由于高级抽象屏蔽掉了大部分硬件层面的影响因素,实际编码过程中很少涉及此类话题[^5]。 --- ### 总结 综上所述,Python 虽然缺乏严格意义下的内置结构体语法糖衣,但凭借强大的 OOP 支持加上专用工具库的帮助完全可以胜任相应任务。无论是追求极致效率还是注重代码优雅度都可以找到合适的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值