• 关于命名元组的归纳回顾


    命名元组:namedtuple,是Python语言里没有引起足够重视的一种数据类型。这是Python中容易被忽略的神奇功能之一。

    当需要定义一个类时,namedtuple是一个很好的选择。

    那么命名元组以及它有什么特性?我们可以把namedtuples看作是Python内置的元组数据类型的扩展。

    Python的元组是一种用于对任意对象进行分组的简单数据结构。元组的内容是不可变的,一旦被创建,数据元素就不能被修改。如下:

    元组有一个缺点,存储在其中的数据只能通过索引来访问。你不能对存储在元组中的单个属性进行命名。这会影响代码的可读性。
        而且,元组通常是一个ad-hoc结构。你很难确保两个元组存储有相同数量的字段和相同的属性。这使得当混合字段顺序时很容易引入“slip-of-the-mind”的bug。

    Namedtuples解决的问题

        Namedtuples主要用来解决如下两个问题。

        首先,namedtuples和常规元组一样,它的内容是不可改变的。 一旦你将数据存储在其中,就不能再修改。

        除此之外,命名元组也是,命名的元组。可以通过唯一的标识符来访问存储在其中的对象。您不必记住元素的下标索引,也不必为了记忆方便把索引定义为常量。

        一个典型的命名元组如下所示:

        使用命名元组前需要先导入collections模块。Python 2.6的标准库中即包含。在上面的例子里,定义了一个简单的命名元组数据类型:“Car”,包含“color” 和“mileage”两个字段。

    也许你你会发现上面的语法有一点怪:为什么我们把两个字段写为一个字符串“color mileage”?

    答案是因为命名元组的工厂函数会在字段字符串后默认调用split()函数对字段进拆解。所以上面的写法就是下面写法的快捷方式:

          也可以直接把字段写成列表形式。这样写的优点是,把字段使用多行分隔,利于代码格式化。

        接下来可以使用“Car”的工厂函数创建"car"对象了,就创建一个类对象“Car”,并且创建了参数值为“color” 和“mileage”的构造函数。

        元组的解包以及带有*函数参数的解包也可正常工作。

        命名元组中元素的即可以通过ID来访问,也可以通过其索引来访问。这样命名元组可以直接替代常规的元组。

        命名元组的输出甚至可以是一个标准的字符串表达式,如下,这样省去了不少的输入冗余。

        像元组一样,命名元组的内容也是不可修改的。当你试图重写其中字段值时,系统会抛出AttributeError异常:

        在Python内部,命名元组是通过一个常规的类对象实现的。但是在内存使用效率上比常规类要高,和正常元组一样。

        你可以把命名元组看做是一个自定义的不可修改的类的快捷方式,但是更节约内存。

    命名元组的子类

        因为命名元组是在常规类的基础上构建的,所以也可以添加方法到命名元组的类中。举个例子,你通过可以添加方法和属性扩展这个类,和扩展常规的类一样。例子如下:

    我们可以创建对象MyCarWithMethods,并且定义一个 hexcolor()方法,结果如下

    这个方法可能看起来有点笨拙。但是当你想得到一个不可修改的类时可以这么试一下。但是注意别搬起石头砸了自己的脚!

    举个例子,由于命名元组的内部构建机制,添加一个新的不可改变的字段是比较麻烦的。最简单的方法就是利用基本元组的._field属性。

        结果如下:


    内置帮助函数

        除了._fields属性,每个命名元组实例还内置了一些非常有用的帮助函数。这些函数都以下划线开头,通常用下划线开头表示它们是私有的方法或者属性,不属于类或者模块的公共接口。

        在命名元组中这些以下划线命名的函数方法则有不同的含义:这些帮助函数或者属性是命名元组公共接口的一部分。之所以这么命名是为了避免和用户自定义的元组字段冲突。您可以随意使用这些帮助函数。

        下面我会给大家展示一些十分有用的命名元组的帮助函数,我们以 _asdict() 函数为例,此函数返回值是一个字典,字典内容是命名元组中存储的元素,如下:

        当你使用JSON样式的输出时,这个函数能避免输入错误,相当有用,举例如下:

        另一个有用的帮助函数是 _replace() ,它会生成当前元组的一个副本(浅拷贝),并且允许用户对其中字段进行选择性替换。

        最后,_make()类方法可以用来在序列或者迭代中创建一个新的命名元组实例,如下:

    什么时候使用命名元组

        命名元组是使代码变得简洁有效的一个简单快速的方法。它通过更好的结构化数据也增强了代码的可读性。

        举个例子,我发现把有混合数据的字典这样的 ad-hoc数据类型用命名元组来代替,能够更清楚的表达我的意图。当我把数据作为命名元组重构时,代码中面临的一些问题,总能找到意想不到的解决办法。    

        使用命名元组处理非结构化的元组和字典,也会让我的同事们工作变的轻松,因为函数直接传递的数据是“自解释的”,非常容易理解(在某种程度上)。

        另一方面,如果命名元组无法使您的代码变得更简洁,更易读,可维护性更高,我就不建议使用它们。因为“一件事太好的话可能就是坏事了”。 

    谨慎的使用命名元组的话,无疑会使您的代码更好,更富有表现力。

    需要记住的事项

      • collection.namedtuple,是一个自定义的不可修改的类的快捷方式,但是更节约内存。

      • 命名元组通过更容易让人理解的方式结构化您的数据,使您的代码更干净整洁。

      • 命名元组提供了一些十分有用的以下划线开头帮助函数,您可以放心使用它们。

  • 相关阅读:
    极高效内存池实现 (cpu-cache)
    gles2.0环境的在windows上的建立
    使用OpenGL绘制 shapefile文件 完成最基本的gis操作
    纯C++安卓开发 (ndk)系列之 ---- 常见问题
    如何用 纯C++(ndk)开发安卓应用 ?
    Android-NDK处理用户交互事件
    图解-安卓中调用OpenGL
    图解安卓-c++开发-通过java 调用c++ jni的使用
    搭建安卓开发环境 hello world andriod
    关于socket通讯,如何才能高效?
  • 原文地址:https://www.cnblogs.com/pyxiaomangshe/p/9202681.html
Copyright © 2020-2023  润新知