namedtuple工厂函数,创造一个像实例对象的元祖(感觉到了Python的奇妙与可爱之处)。

发现了namedtuple将大大的方便对象实例化的过程,底层我觉的应该应用了描述符的相关指令__set__,__get__,__delete__等等,深的不讲了,我给自己记号一下如何把这个函数用好。

基本概念

  1. namedtuple是一个 工厂函数,定义在python标准库的collections模块中,使用此函数可以创建一个可读性更强的元组
  2. namedtuple函数所创建(返回)的是一个 元组的子类(python中基本数据类型都是类,且可以在buildins模块中找到)
  3. namedtuple函数所创建元组,中文名称为 具名元组
  4. 在使用普通元组的时候,我们只能通过index来访问元组中的某个数据
  5. 使用具名元组,我们既可以使用index来访问,也可以使用具名元组中每个字段的名称来访问
  6. 值得注意的是,具名元组和普通元组所需要的内存空间相同,所以 不必使用性能来权衡是否使用具名元组
if sys.version_info >= (3, 7):
    def namedtuple(typename: str, field_names: Union[str, Iterable[str]], *,
                   rename: bool = ..., module: Optional[str] = ..., defaults: Optional[Iterable[Any]] = ...) -> Type[tuple]: ...
elif sys.version_info >= (3, 6):
    def namedtuple(typename: str, field_names: Union[str, Iterable[str]], *,
                   verbose: bool = ..., rename: bool = ..., module: Optional[str] = ...) -> Type[tuple]: ...
else:
    def namedtuple(typename: str, field_names: Union[str, Iterable[str]],
                   verbose: bool = ..., rename: bool = ...) -> Type[tuple]: ...

进去源码里面可以看到,应该当Python的版本不同时,里面的默认参数也会不同,我是3.7的,我看的数版本肯定不是3.7的,所以介绍的里面不全。

第一个参数:typename是调用namedtuple函数时作为新创建的类名称。

第二个参数:field_names可以传入str或者可迭代的对象的str[‘color‘,‘age‘]类似这种,或者字符串‘color age‘属性之间必须空格,内部应该执行了split命令,还有就是里面的str不能是Python里面的关键字,比如def,class。

后面的参数书上没介绍,网上找来部分资料。

rename

  • 注意的参数中使用了*,其后的所有参数必须指定关键字
  • 参数为布尔值
  • 默认为False。当我们指定为True时,如果定义field_names参数时,出现非法参数时,会将其替换为位置名称。如[‘abc‘, ‘def‘, ‘ghi‘, ‘abc‘]会被替换为[‘abc‘, ‘_1‘, ‘ghi‘, ‘_3‘]

defaults

  • 参数为None或者可迭代对象
  • 当此参数为None时,创建具名元组的实例时,必须要根据field_names传递指定数量的参数
  • 当设置defaults时,我们就为具名元组的元素赋予了默认值,被赋予默认值的元素在实例化的时候可以不传入
  • defaults传入的序列长度和field_names不一致时,函数默认会右侧优先
  • 如果field_names[‘x‘, ‘y‘, ‘z‘]defaults(1, 2),那么x是实例化必填参数,y默认为1z默认为2

上代码。

from collections import namedtuple

Car = namedtuple(‘Car‘, ‘color brand def‘, rename=True, defaults=(‘red‘, ‘honda‘))

car = Car(‘temp‘)        # 初始化实例,由于前面已经有了两个默认值,就填写了少的一个
print(car)               # 输出实现显示格式,Car(color=‘temp‘, brand=‘red‘, _2=‘honda‘)
# 很好玩的默认赋值方式,默认的赋值是从后面往前面自动匹配,因为我最后的是非法字符def
# rename选项打开以后自动转换成字符_2,然后进行赋值
print(car.color)          # 通过.取出属性
print(car[1])             # 通过索引取出属性
print(‘‘.join(car))       # 有着元祖的特性进行内容拼接。
car.color = ‘blue‘         # 有着元祖的特性,内部元素不容修改
Traceback (most recent call last):
  File "/Users/shijianzhong/Desktop/bit_coin/test_file/test_namedtuple.py", line 10, in <module>
    car.color = ‘blue‘
AttributeError: can‘t set attribute
Car(color=‘temp‘, brand=‘red‘, _2=‘honda‘)
temp
red
tempredhonda

通过代码显示可以看出,实例出来的对象既有元祖的全部特性,还像一个只读的自定义对象。类似MappingProxyType(实例)

namefile还提供了一些游泳的辅助方法。

第一个_fields,用继续另外一个基类元祖的字段。

print(Car._fields)
(‘color‘, ‘brand‘, ‘_2‘)

直接输出Car的字段,将三个属性输出,所以,如果想继承的话,可以这么写

Car2 = namedtuple(‘Car2‘, Car._fields+(‘other‘,))

记得上面的参数小括号里面的逗号,因为元祖+元祖才返回一个元祖。

第二个是_asdict

print(car._asdict())
OrderedDict([(‘color‘, ‘temp‘), (‘brand‘, ‘red‘), (‘_2‘, ‘honda‘)])

生成了一个有序的字典,这样的话,就可以按照字典的方式,随意操作了。

第三个是_replace,用来替换里面的参数,返回一个新实例

n_car = car._replace(brand=‘blue‘)
print(n_car)
Car(color=‘1‘, brand=‘blue‘, _2=‘temp‘)

这个刚开犯傻了一下,以为是列表没有给予赋值,car自身会发生变换,还是脑子秀逗了,对于元祖的任何操作,跟字符串都一样,因为对象本身是不可变的,所以当有变化发生时,需要变量名来接受修改后的参数。

最后一个_make类方法,用来从序列或迭代对象中创建nametuple的新实例。

car2 = Car._make([‘purple‘,‘audi‘,‘tt‘])
print(car2)
Car(color=‘1‘, brand=‘blue‘, _2=‘temp‘)
Car(color=‘purple‘, brand=‘audi‘, _2=‘tt‘)

最后的参数链接,作者写的比我详细,大家可以参考学习下。

参考链接:https://www.jianshu.com/p/60e6484a7088

原文地址:https://www.cnblogs.com/sidianok/p/11876922.html

时间: 2024-11-06 07:47:06

namedtuple工厂函数,创造一个像实例对象的元祖(感觉到了Python的奇妙与可爱之处)。的相关文章

collections.namedtuple工厂函数

collections.namedtuple是一个工厂函数,它可以用来构建一个带字段名的元组和一个有名字的类——这个带名字的类对调试程序有很大帮助. 以往存在一定量数据习惯以列表或json的方式保存,例如: 列表: 1 nodes = [ 2 ['192.168.1.1', 22, 'guest'], 3 ['192.168.1.2', 22, 'guest'], 4 ] 5 for i in nodes: 6 print(i[1]) 列表的坏处是以数字作脚注,数据对应关系不直观 json: 1

More Effective C++ 条款31 让函数根据一个以上的对象类型来决定如何虚化

1. 假设要编写一个发生在太空的游戏,其中有飞船(spaceship),太空站(space station)和小行星(ssteroid),使它们继承自一个抽象基类GameObject,整个继承体系像这样: class GameObject { ... }; class SpaceShip: public GameObject { ... }; class SpaceStation: public GameObject { ... }; class Asteroid: public GameObj

JavaScript中的构造函数和工厂函数

JavaScript中的工厂函数 1 function crateHero (name,blood,weapoon) { 2 var o = new Object(); 3 o.name = name; 4 o.blood = blood; 5 o.weapoon = weapoon; 6 o.attch = function () { 7 console.log(this.name+"用"+this.weapoon+"进行了攻击"); 8 } 9 return o

springboot启动流程(一)构造SpringApplication实例对象

所有文章 https://www.cnblogs.com/lay2017/p/11478237.html 启动入口 本文是springboot启动流程的第一篇,涉及的内容是SpringApplication这个对象的实例化过程.为什么从SpringApplication这个对象说起呢?我们先看一段很熟悉的代码片段 @SpringBootApplication public class SpringBootLearnApplication { public static void main(Str

元祖、函数详解

元组(tuple):大体跟列表一样,主要是元组不能增删改,相当于只读. 函数:在程序当中,很多重复数据需要操作了,while和if等就不好用了,这是用函数,模块化,容易调用.把整体当做一个函数,叫封装. ctrl +d选下个,当选中改就能都修改,ctrl+右加上什么就都加上了. 设置vim,tab键和可视化>>都可移动4个空格方式: vim /etc/vimrc 在最后添加如下几行 set smartindent set tabstop=4 set shiftwidth=4 set expan

用工厂函数封装对象

工厂函数是在方法中建立一个Object空对象,然后再对此对象添加属性和方法,然后把Object对象返回 <html> <head> <title>工厂函数封装对象</title> <script type="text/javascript"> // 工厂函数模式封装对象 //特点:返回结果为对象的函数,在用工厂函数创建对象的时候,一定要new function fn(nianling){ var obj=new object(

Flask框架工厂函数用法实例分析

在我们开始学习FLask的时候,创建应用的实例是用app=Flask(name)来做的,但是当我们想创建多个不同配置的实例的时候咋办呢,每次都要改是不是很烦,那为了减少麻烦,我们可以采用调用一个create_app函数来返回应用实例的方法,这就是工厂方法的大概意思啦! 文字说的再多也难以帮助理解,看代码示例: 1.最初的写法 ? 1 2 3 4 5 6 7 8 #__init__.py里面创建实例,应用实例对象创建完再引入视图函数的模块,因为这时候视图函数上的@app.route()才有效 fr

对象工厂函数与构造函数

本文内容: 1.概述 2.使用工厂函数创建对象 3.定义对象“构造”函数 4.对象的constructor属性 5.以普通方式调用的对象“构造”函数 ★概述: 使用对象字面量,或者向空对象中动态地添加新成员,是最简单易用的对象创建方法.然而,除了这两种常用的对象创建方式,JavaScript还提供了其他方法创建对象. ★使用工厂函数创建对象 我们可以编写一个函数,此函数的功能就是创建对象,可以将其称为“对象工厂方法”. ★ 定义对象“构造”函数 注意点:对象构造函数首字母大写:内部使用this关

Javascript我学之六对象工厂函数与构造函数

本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘. 概述 使用对象字面量,或者向空对象中动态地添加新成员,是最简单易用的对象创建方法. 然而,除了这两种常用的对象创建方式,JavaScript还提供了其他方法创建对象. 1).使用工厂函数创建对象 我们可以编写一个函数,此函数的功能就是创建对象,可将其称为“对象工厂方法”. 1 //工厂函数 2 function createPerson(name, age, job) { 3 var o = new Object(); 4 o.name