首页 > 其他分享 >namedtuple工厂函数精讲

namedtuple工厂函数精讲

时间:2022-10-31 22:58:33浏览次数:77  
标签:11 namedtuple 函数 22 Point 精讲 元组 具名

首先,我会介绍下使用namedtuple所需要了解的基本概念,然后讲解如何使用namedtuple,最后使用namedtuple来创建一摞纸牌。理解这些之后,就可以权衡利弊,并在生产中使用

基本概念

  1. namedtuple是一个 工厂函数,定义在python标准库的collections模块中,使用此函数可以创建一个可读性更强的元组
  2. namedtuple函数所创建(返回)的是一个 元组的子类(python中基本数据类型都是类,且可以在buildins模块中找到)
  3. namedtuple函数所创建元组,中文名称为 具名元组
  4. 在使用普通元组的时候,我们只能通过index来访问元组中的某个数据
  5. 使用具名元组,我们既可以使用index来访问,也可以使用具名元组中每个字段的名称来访问
  6. 值得注意的是,具名元组和普通元组所需要的内存空间相同,所以 不必使用性能来权衡是否使用具名元组

如何使用

namedtuple是一个函数,我们先来看下他的参数

参数解析

def namedtuple(typename, field_names, *, rename=False, defaults=None, module=None):

有两个必填参数typenamefield_names
typename

  • 参数类型为字符串
  • 具名元组返回一个元组子对象,我们要为这个对象命名,传入typename参数即可

field_names

  • 参数类型为字符串序列
  • 用于为创建的元组的每个元素命名,可以传入像['a', 'b']这样的序列,也可以传入'a b''a, b'这种被逗号空格分割的单字符串
  • 必须是合法的标识符。不能是关键字如class,def

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

基本使用

理解了namedtuple函数的参数,我们就可以创建具名元组了

>>> Point = namedtuple('Point', ['x', 'y'])  # 返回一个名为`Point`的类,并赋值给名为`Point`的变量
>>> p = Point(11, y=22)     # 可以根据参数的位置,或具名参数来实例化(像普通的类一样)
>>> p[0] + p[1]             # 具名元组可以像普通元组一样通过`index`访问
33
>>> x, y = p                # 具名元组可以像普通元组一样解包
>>> x, y
(11, 22)
>>> p.x + p.y               # 具名元组还可以通过属性名称访问元组内容
33
>>> p                       # 具名元组在调用`__repr__`,打印实例时,更具可读性
Point(x=11, y=22)

具名元组在存储csv或者sqlite3返回数据的时候特别有用

EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')

import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
    print(emp.name, emp.title)

import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
    print(emp.name, emp.title)

特性

具名元组除了拥有继承自基本元组的所有方法之外,还提供了额外的三个方法和两个属性,为了防止命名冲突,这些方法都会以下划线开头

_make(iterable)
这是一个类函数,参数是一个迭代器,可以使用这个函数来构建具名元组实例

>>> t = [11, 22]
>>> Point._make(t)
Point(x=11, y=22)

_asdict()
实例方法,根据具名元组的名称和其元素值,构建一个OrderedDict返回

>>> p = Point(x=11, y=22)
>>> p._asdict()
OrderedDict([('x', 11), ('y', 22)])

_replace(**kwargs)
实例方法,根据传入的关键词参数,替换具名元组的相关参数,然后返回一个新的具名元组

>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)

>>> for partnum, record in inventory.items():
...     inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())

_fields
这是一个实例属性,存储了此具名元组的元素名称元组,在根据已经存在的具名元组创建新的具名元组的时候使用

>>> p._fields            # view the field names
('x', 'y')

>>> Color = namedtuple('Color', 'red green blue')
>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
>>> Pixel(11, 22, 128, 255, 0)
Pixel(x=11, y=22, red=128, green=255, blue=0)

_fields_defaults
查看具名元组类的默认值

>>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
>>> Account._fields_defaults
{'balance': 0}
>>> Account('premium')
Account(type='premium', balance=0)

使用技巧

  1. 使用getattr获取具名元组元素值
>>> getattr(p, 'x')
11
  1. 将字典转换为具名元组
>>> d = {'x': 11, 'y': 22}
>>> Point(**d)
Point(x=11, y=22)
  1. 既然具名元组是一个类,我们当然可以随心所欲的进行定制
>>> class Point(namedtuple('Point', ['x', 'y'])):
...     __slots__ = ()
...     @property
...     def hypot(self):
...         return (self.x ** 2 + self.y ** 2) ** 0.5
...     def __str__(self):
...         return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

>>> for p in Point(3, 4), Point(14, 5/7):
...     print(p)
Point: x= 3.000  y= 4.000  hypot= 5.000
Point: x=14.000  y= 0.714  hypot=14.018

__slots__值的设置可以保证具名元组保持最小的内存占用

namedtuple纸牌

import collections
# 将纸牌定义为具名元组,每个纸牌都有等级和花色
Card = collections.namedtuple('Card', 'rank suit')

class FrenchDeck:
    # 等级2-A
    ranks = [str(n) for n in range(2,11)] + list('JQKA')
    # 花色红黑方草
    suits = 'spades diamonds clubs hearts'.split()
    # 构建纸牌
    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]
    # 获取纸牌
    def __getitem__(self, position):
        return self._cards[position]

>>> french_deck = FrenchDeck()
>>> french_deck[0]
Card(rank='2', suit='spades')
>>> french_deck[0].rank
'2'
>>> french_deck[0].suit
'spades'


作者:天边一钩残月带三星
链接:https://www.jianshu.com/p/60e6484a7088
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。  

标签:11,namedtuple,函数,22,Point,精讲,元组,具名
From: https://www.cnblogs.com/clark1990/p/16846172.html

相关文章

  • matlab最小二乘法数据拟合函数详解
    定义:最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与......
  • Linux C语言 Makefile 的使用 函数
    创建三个.c文件终端输入:创建目录:mkdirMakefile进入目录:cdMakefile使用gedit:gedit第一个文件:main.c#include<stdio.h>#include"input.h"#include"calcu.h"intm......
  • 函数的声明与定义 include .h .c
    1函数的定义函数定义的格式:数值返回类型 参数名(参数形式)               {执行语句               ......
  • gdb 查看函数调用堆栈(frame概念)
    摘自:https://www.cnblogs.com/xiaoshiwang/p/12893748.html1,使用bt(backtrace)命令查看当前堆栈(gdb)bt#0muduo::Poller::poll(this=0x62e010,timeoutMs=10000,......
  • 学习笔记- PHP回调函数
    PHP回调函数call_user_funccall_user_func—把第一个参数作为回调函数调用,其余参数是回调函数的参数<?phpcall_user_func($_GET['a1'],$_GET['a2']);?>//xx......
  • 学习笔记-绕过php禁用函数
    bypass_disable_function相关文章&Source&ReferenceCTF中的命令执行绕过无需sendmail:巧用LD_PRELOAD突破disable_functionsphp中函数禁用绕过的原理与利用相......
  • 6、函数
    6函数6.1概述作用:将一段经常使用的代码封装起来,减少重复代码一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。6.2函数的定义函数的定义一般主要有5个......
  • [单片机框架][os层] RTX5 中间件 公共函数
    KeilRTX5是一种免版税、确定性、全功能的实时操作系统,它实现了CMSIS-RTOSAPIv2,这是一种适用于基于Cortex-M处理器的设备的通用RTOS接口。功能包括定期激活定时器功......
  • sqlserver 分区函数去重复排序
     sqlserver分区函数去重复排序--获取,FlowID去重复的,按时间排序的,前一行select*from(select*,row_number()over(partitionbyFlowIDorderbyConfirmDat......
  • linux中断子系统(二) - 注册用户中断处理函数
    区别系统中断函数和用户中断函数和前面一篇文章区别开来,之所以要区别系统中断函数和用户中断函数,这是我自己的理解。来看一个结构体:structirq_desc{unsignedint......