Python中namedtuple的使用

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

引言

在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模块测试一个个元素的元组和namedtuple的创建效率:

 from collections import namedtuple import timeit def test_normal_tuple(): t = tuple(range()) def test_named_tuple(): Person = namedtuple("Person", list(range())) tuple = Person(*range()) 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.02637 named tuple : 8.2231 

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

2.访问效率

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

 from collections import namedtuple import timeit Person = namedtuple("Person", list(range())) tuple = Person(*range()) def test_normal_tuple(): t = tuple(range()) for i in range(len(t)): a = t[i] def test_named_tuple(): for i in range(): 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.9551 named tuple : 6.6687 

可以看到,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.00 named tuple : 0.00 

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

结论

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/19542.html

(0)
上一篇 2024-09-05
下一篇 2024-09-05

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注