在看pytest测试实战一书中,看到了python namedtuple这个模块,在网上查询了一下还挺好用的,记录下来:
摘自https://www.jianshu.com/p/60e6484a7088
首先,我会介绍下使用namedtuple所需要了解的基本概念,然后讲解如何使用namedtuple,最后使用namedtuple来创建一摞纸牌。理解这些之后,就可以权衡利弊,并在生产中使用
namedtuple是一个函数,我们先来看下他的参数
有两个必填参数typename和field_namestypename
参数类型为字符串具名元组返回一个元组子对象,我们要为这个对象命名,传入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默认为1,z默认为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)__slots__值的设置可以保证具名元组保持最小的内存占用
转载于:https://www.cnblogs.com/linwenbin/p/11282492.html
