Python中namedtuple的使用

引言

在Python中,有时需要自定义简单但是有名字的记录类型,如果使用字典或普通元组,通常会显得有点笨重。此时,namedtuple就成为了一个很好的选择。namedtuple是Python标准库collections中的一个函数,用于创建和实例化类似于元组的对象,但这些对象有名称,可以像字典一样通过名称来访问字段。namedtuple相当于一个轻量级的类定义器,它本质上是一个Python类,可以像其他类一样继承、实例化、序列化和扩展。

正文

一、namedtuple的使用方法

namedtuple的使用方法与普通元组非常相似。首先需要导入collections库,然后使用namedtuple函数来定义一个命名元组。定义时需要提供两个参数:元组名称和元素名称列表。下面是一个简单的例子:

from collections import namedtuple
#定义一个命名元组
Person = namedtuple("Person", ["name", "age"])
#使用命名元组
person = Person(name="Tom", age=18)
print(person.name)  # Tom

在上面的例子中,定义了一个Person命名元组,包含name和age两个字段。在实例化时,使用关键字参数来指定字段的值,可以像普通元组一样通过索引或名称来访问元素。但不同的是,通过名称访问元素时更直观和安全。

二、namedtuple与普通元组的比较

在使用namedtuple之前,可以先看一下普通元组的缺陷。

  • 元组和其它序列一样是有序的。当元素需要赋予语义时,就需要借助位置来访问元素。这会降低程序的可读性,并让代码更加脆弱(如果代码依赖于元组中的位置,那么当元组结构发生变化时,很容易出错)。
  • 在表达简单的对象时,元组常常是有用的——如果需要将其作为函数的参数,并且只有少数几个值是有意义的。但是,当元组变得更大,或者需要添加一些方法或属性来扩展元组时,这时候使用类会更好。
  • 元组是不可变的,因此如果想在元素被赋值后修改它们是不可能的。这样如果需要在修改后返回相似但是不同的对象时,就需要使用其他的数据类型(如列表)来存储数据。
  • 在元组中添加、删除或修改元素会非常困难。当元组项数变得非常庞大时,元组会变得笨重,在这种情况下,尽量使用更合适的数据结构。

三、namedtuple的高级用法

namedtuple本身是可以继承的,这意味着其可以和其他的类一样进行扩展,添加自己的方法和属性:

from collections import namedtuple
#定义一个命名元组
Animal = namedtuple("Animal", ["name", "age"])
#定义一个Cat类,并继承Animal类
class Cat(Animal):
    def __str__(self):
        return "cat: {name}, {age}".format(name=self.name, age=self.age)

cat = Cat(name="Tom", age=3)
print(cat)  # cat: Tom, 3

此外,namedtuple还支持各种继承和多重继承的方式,可以方便地与需要继承的类和对象进行交互。

四、namedtuple的性能测试

对于一个类定义器来说,其性能是一个非常重要的因素,下面从创建、访问和执行效率三个方面对namedtuple进行性能测试,和普通元组进行比较。

1.创建效率

使用timeit模块测试一个10000000个元素的元组和namedtuple的创建效率:

from collections import namedtuple
import timeit

def test_normal_tuple():
    t = tuple(range(10000000))

def test_named_tuple():
    Person = namedtuple("Person", list(range(10000000)))
    tuple = Person(*range(10000000))

if __name__ == "__main__":
    normal_time = timeit.timeit("test_normal_tuple()", setup="from __main__ import test_normal_tuple", number=1000)
    named_time = timeit.timeit("test_named_tuple()", setup="from __main__ import test_named_tuple", number=1000)
    print("normal tuple :", normal_time)
    print("named tuple  :", named_time)

得到结果如下:

normal tuple : 1.4164350395202637
named tuple  : 8.236930131912231

可以看到,namedtuple创建的速度比普通元组慢,因为它需要额外的计算来生成所需要的类定义,但这种差异在实际应用中并不会影响太多。

2.访问效率

使用timeit模块测试一个10000000个元素的元组和namedtuple的访问效率:

from collections import namedtuple
import timeit

Person = namedtuple("Person", list(range(10000000)))
tuple = Person(*range(10000000))

def test_normal_tuple():
    t = tuple(range(10000000))
    for i in range(len(t)):
        a = t[i]

def test_named_tuple():
    for i in range(10000000):
        a = tuple[i]

if __name__ == "__main__":
    normal_time = timeit.timeit("test_normal_tuple()", setup="from __main__ import test_normal_tuple", number=1000)
    named_time = timeit.timeit("test_named_tuple()", setup="from __main__ import test_named_tuple", number=1000)
    print("normal tuple :", normal_time)
    print("named tuple  :", named_time)

得到结果如下:

normal tuple : 5.558712959289551
named tuple  : 6.515319109916687

可以看到,namedtuple与元组在访问效率上并无明显区别。

3.执行效率

使用timeit模块测试一个空操作的元组和namedtuple的执行效率:

from collections import namedtuple
import timeit

Person = namedtuple("Person", ["name", "age"])
tuple = Person(name="Tom", age=3)

def test_normal_tuple():
    pass

def test_named_tuple():
    pass

if __name__ == "__main__":
    normal_time = timeit.timeit("test_normal_tuple()", setup="from __main__ import test_normal_tuple", number=1000)
    named_time = timeit.timeit("test_named_tuple()", setup="from __main__ import test_named_tuple", number=1000)
    print("normal tuple :", normal_time)
    print("named tuple  :", named_time)

得到结果如下:

normal tuple : 0.0016641616821289062
named tuple  : 0.0016469955444335938

可以看到,namedtuple与元组在执行效率上几乎无差别。

结论

总体来说,namedtuple相比普通元组来说有更好的可读性,同时它本身也具备扩展性和继承性。尽管在创建方面不如普通元组快,但巨大的拓展性和易用性弥补了这一点缺陷。在实际项目中,使用namedtuple可以提高代码的可读性和可维护性,减少由于人为疏忽带来的错误。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/219980.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-09 11:02
下一篇 2024-12-09 11:02

相关推荐

  • Python中引入上一级目录中函数

    Python中经常需要调用其他文件夹中的模块或函数,其中一个常见的操作是引入上一级目录中的函数。在此,我们将从多个角度详细解释如何在Python中引入上一级目录的函数。 一、加入环…

    编程 2025-04-29
  • 如何查看Anaconda中Python路径

    对Anaconda中Python路径即conda环境的查看进行详细的阐述。 一、使用命令行查看 1、在Windows系统中,可以使用命令提示符(cmd)或者Anaconda Pro…

    编程 2025-04-29
  • Python周杰伦代码用法介绍

    本文将从多个方面对Python周杰伦代码进行详细的阐述。 一、代码介绍 from urllib.request import urlopen from bs4 import Bea…

    编程 2025-04-29
  • Python列表中负数的个数

    Python列表是一个有序的集合,可以存储多个不同类型的元素。而负数是指小于0的整数。在Python列表中,我们想要找到负数的个数,可以通过以下几个方面进行实现。 一、使用循环遍历…

    编程 2025-04-29
  • Python计算阳历日期对应周几

    本文介绍如何通过Python计算任意阳历日期对应周几。 一、获取日期 获取日期可以通过Python内置的模块datetime实现,示例代码如下: from datetime imp…

    编程 2025-04-29
  • 蝴蝶优化算法Python版

    蝴蝶优化算法是一种基于仿生学的优化算法,模仿自然界中的蝴蝶进行搜索。它可以应用于多个领域的优化问题,包括数学优化、工程问题、机器学习等。本文将从多个方面对蝴蝶优化算法Python版…

    编程 2025-04-29
  • Python程序需要编译才能执行

    Python 被广泛应用于数据分析、人工智能、科学计算等领域,它的灵活性和简单易学的性质使得越来越多的人喜欢使用 Python 进行编程。然而,在 Python 中程序执行的方式不…

    编程 2025-04-29
  • Python字典去重复工具

    使用Python语言编写字典去重复工具,可帮助用户快速去重复。 一、字典去重复工具的需求 在使用Python编写程序时,我们经常需要处理数据文件,其中包含了大量的重复数据。为了方便…

    编程 2025-04-29
  • Python编程二级证书考试相关现已可以上网购买

    计算机二级Python考试是一项重要的国家级认证考试,也是Python编程的入门考试。与其他考试一样,Python编程二级证书的考生需要进入正式考试,而为了备考,这篇文章将详细介绍…

    编程 2025-04-29
  • Python清华镜像下载

    Python清华镜像是一个高质量的Python开发资源镜像站,提供了Python及其相关的开发工具、框架和文档的下载服务。本文将从以下几个方面对Python清华镜像下载进行详细的阐…

    编程 2025-04-29

发表回复

登录后才能评论