python class namedtuple 效率_菜鸟世界 -python进阶之 namedtuple

1、namedtuple

tuple是不可变序列,当你不希望外界可以随意的改变你的函数返回值的时候,不妨将你的返回值以tuple的形式返回,tuple还可以做为字典的key,这些都是tuple的独到之处,此外,由于存储的方式不同,相同元素的tuple 要比list更快,使用的内存更少。

tuple虽然有这么多优点,但是呢,在使用的时候,你不得不用下角标来访问它的元素,这样对于代码的可读性来说是一种折损。

namedtuple弥补了tuple的这一缺陷,使得你可以像使用对象属性那样去访问数据

2、示例

2.1 代码

# coding=utf-8

from collections import namedtuple

Book = namedtuple('Book', ['name', 'price', 'count'])

book1 = Book(name='python', price=100.0, count=10)

print book1

print book1.name

print book1.price

print book1.count

2.2  如何创建

在上面的这段代码中,首先定义了一个namedtuple,第一个参数指定了它的类型,第二个参数则指定了字段名称,第二个参数除了写成list的形式,还可以写成字符串的形式,以空格分割,例如

Book = namedtuple('Book', 'name price count')

2.3 属性不可改变

如果你试图改变book1对象的某个属性,程序会直接报错的,因为它是一个特殊的tuple

2.4 更便捷的赋值过程

对于上面代码中的属性赋值过程,你可能会感到有些为难,因为如果字段特别多,那么一个一个的写代码去赋值就变得非常繁琐,如果你手里拥有的数据是一个字典,那么还可以这样去创始化它

book_dict = {

'name': 'c++',

'price': 99,

'count': 10

}

book2 = Book(**book_dict)

print book2

3、 namedtuple究竟是什么

不妨先打印一下Book

print Book

得到的结果是

这说明, namedtuple('Book', 'name price count')  返回的是一个类,Book恰好是我们传入的第一个参数,你可以将第一个参数修改成其他单词,然后再打印观察效果就会明白,第一个参数定义的是类的名字

深入namedtuple  的实现一探究竟

在 collections.py 文件中的293行开始,是对namedtuple的定义,注意看 356行的  class_definition  和  374 行的 exec class_definition in namespace

356行都是对属性的处理,356行,将这些数据整合成一个字符串,374行则对这个字符串进行了执行,或者说编译,得到的就是一个类

那么这个类又是如何生成的呢?

293行定义了类的模板

_class_template = '''\

class {typename}(tuple):

'{typename}({arg_list})'

__slots__ = ()

_fields = {field_names!r}

def __new__(_cls, {arg_list}):

'Create new instance of {typename}({arg_list})'

return _tuple.__new__(_cls, ({arg_list}))

@classmethod

def _make(cls, iterable, new=tuple.__new__, len=len):

'Make a new {typename} object from a sequence or iterable'

result = new(cls, iterable)

if len(result) != {num_fields:d}:

raise TypeError('Expected {num_fields:d} arguments, got %d' % len(result))

return result

def __repr__(self):

'Return a nicely formatted representation string'

return '{typename}({repr_fmt})' % self

def _asdict(self):

'Return a new OrderedDict which maps field names to their values'

return OrderedDict(zip(self._fields, self))

def _replace(_self, **kwds):

'Return a new {typename} object replacing specified fields with new values'

result = _self._make(map(kwds.pop, {field_names!r}, _self))

if kwds:

raise ValueError('Got unexpected field names: %r' % kwds.keys())

return result

def __getnewargs__(self):

'Return self as a plain tuple. Used by copy and pickle.'

return tuple(self)

__dict__ = _property(_asdict)

def __getstate__(self):

'Exclude the OrderedDict from pickling'

pass

{field_defs}

'''

这正是奥妙所在,nametuple根据我们传入的两个参数,格式化了这段字符串,然后exec 这段字符串,就生成了一个类,这个类继承了tuple,而后,我们用这个类创建对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值