python中namedtuple的用法

今天 发现了Python 中有一个可以给tuple  一个名字的一个方法,叫namedtuple

from collections import namedtuple



# encoding: utf-8
from collections import namedtuple



person =('name','age','sex','mail')
Person = namedtuple('Person',person,verbose=True)
p = Person('changyubiao',18,"male",'931367095@qq.com')
print type(p)
print p.name ,p.age,p.sex,p.mail

发现是可以 打印出结果的

<class '__main__.Person'>

changyubiao 18 male 931367095@qq.com

觉得这不错, 可以属性名,来访问元祖而不用小标,这样还是比较好,如果特别的属性,就可以通过这种方式。后来看一下,它的官方文档。

namedtuple() factory function for creating tuple subclasses with named fields   ,就是 返回一个子类tuple 用给出 那些字段 ,name ,age ,sex ,mail 等。


collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
Returns a new tuple subclass named typename. The new subclass is used to create tuple-like objects that have fields accessible by attribute lookup as well as being indexable and iterable. Instances of the subclass also have a helpful docstring (with typename and field_names) and a helpful __repr__() method which lists the tuple contents in a name=value format.

The field_names are a sequence of strings such as ['x', 'y']. Alternatively, field_names can be a single string with each fieldname separated by whitespace and/or commas, for example 'x y' or 'x, y'.

Any valid Python identifier may be used for a fieldname except for names starting with an underscore. Valid identifiers consist of letters, digits, and underscores but do not start with a digit or underscore and cannot be a keyword such as class, for, return, global, pass, print, or raise.

If rename is true, invalid fieldnames are automatically replaced with positional names. For example, ['abc', 'def', 'ghi', 'abc'] is converted to ['abc', '_1', 'ghi', '_3'], eliminating the keyword def and the duplicate fieldname abc.

If verbose is true, the class definition is printed just before being built.

Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples.
'''



返回一个名为typename的新的元组子类。新的子类用于创建具有可通过属性查找访问的字段的元组对象,以及可索引和可​​迭代的对象。子类的实例也有一个有用的docstring(带有typename和field_names)和一个有用的__repr __()方法,它以一个name = value格式列出元组内容。

field_names是一串字符串,如['x','y']。或者,field_names可以是单个字符串,每个字段名用空格和/或逗号分隔,例如'x y'或'x,y'。

除了以下划线开头的名称以外,任何有效的Python标识符都可以用于字段名。有效的标识符由字母,数字和下划线组成,但不以数字或下划线开头,不能是关键字,例如class,for,return,global,pass,print或raise。

如果重命名为true,则无效的字段名会自动替换为位置名称。例如,['abc','def','ghi','abc']被转换为['abc','_1','ghi','_3'],消除了关键字def和重复的字段名abc 。

如果verbose为true,则在构建之前打印类定义。

命名的元组实例没有每个实例的字典,所以它们是轻量级的,不需要比常规元组更多的内存。

person =('name','age','sex','mail')
Person = namedtuple('Person',person)

对于第二句话,为什么 要有一个‘Person’  呢?  这个 有什么用呢,之后 我看了实现。 其实官方文档 也说了, namedtuple() 会根据这个typename , 创建一个子类 类名 就是typename , 返回出去,之后赋值给Person ,后面 字段就是属性了,会根据这个这个元祖来生成 类的属性。当然 这些属性必须要满足变量名称的定义规则,不能是关键字,不能以数字开头,等等。否则 会报错的。   有这个参数 verbose=True  就可以看到类的生成过程。让我们来一起看下。

person =('name','age','sex','mail')
Person = namedtuple('Person',person,verbose=True)


在控制台中,就能看到Person 构造过程, 是继承tuple , 一个子类, Person 就是那个类型, 就是namedtuple  第一个参数,这里就解释,为啥要有第一个参数。
class Person(tuple):
    'Person(name, age, sex, mail)'

    __slots__ = ()

    _fields = ('name', 'age', 'sex', 'mail')

    def __new__(_cls, name, age, sex, mail):
        'Create new instance of Person(name, age, sex, mail)'
        return _tuple.__new__(_cls, (name, age, sex, mail))

    @classmethod
    def _make(cls, iterable, new=tuple.__new__, len=len):
        'Make a new Person object from a sequence or iterable'
        result = new(cls, iterable)
        if len(result) != 4:
            raise TypeError('Expected 4 arguments, got %d' % len(result))
        return result

    def __repr__(self):
        'Return a nicely formatted representation string'
        return 'Person(name=%r, age=%r, sex=%r, mail=%r)' % 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 Person object replacing specified fields with new values'
        result = _self._make(map(kwds.pop, ('name', 'age', 'sex', 'mail'), _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

    name = _property(_itemgetter(0), doc='Alias for field number 0')

    age = _property(_itemgetter(1), doc='Alias for field number 1')

    sex = _property(_itemgetter(2), doc='Alias for field number 2')

    mail = _property(_itemgetter(3), doc='Alias for field number 3')

从这里可以看出整个类的构造过程, 也会对namedtuple  有更好的理解。 其实namedtuple  并没有破坏用下标访问

# encoding: utf-8
from collections import namedtuple



person =('name','age','sex','mail')
Person = namedtuple('Person',person,verbose=False)

p = Person('changyubiao',18,"male",'931367095@qq.com')


print p.name ,p.age,p.mail,p.sex

for i in range(0,4):
    print p[i]

 

没有任何问题, 还是 可以正常访问的。


还有一个 namedtuple  一个参数 rename   这个就是 如果的 属性 设置不能作为变量名 , 会直接报错。 如果用rename=True, Python  会自动重新帮你命名,来符合变量的命名规范。来看一个例子

我把Person 的属性 mail  改成了  5mail  肯定不符合规范, Python 构建 子类的时候, 就会报错。

person =('name','age','sex','5mail')
Person = namedtuple('Person',person,verbose=True,)

p = Person('changyubiao',18,"male",'931367095@qq.com')


如果 构造namedtuple 的时候 ,加上 rename=True, 来看下结果

person =('name','age','sex','5mail')
Person = namedtuple('Person',person,verbose=True,rename=True)



这里明显可以看出 第四个字段,变成了 _3 名称,python 自己重新的命名。

访问下 属性

print p.name ,p.age,p._3,p.sex

for i in range(0,4):
    print (p[i])


成功的 访问到了邮箱了,这就是rename  的作用。


总结: 对于这种namedtuple  有什么好处,显而易见 就是方便 访问,不需要记住下标,可以访问元素,元祖 的元素比较多的时候,用这个还是不错的。

但是 问题来了, 为什么不用字典呢?  和namedtuple  有什么区别呢? 

以下是我的这个拙见:

namedtuple    是只读的,第一  不能修改元祖,它还是元祖,第二 它是有序的。第三, 查找速度man,  它的优点呢? 占用内存小(和字典相比)

字典的特点  , 第一  ,value 的值是可以更改的,第二 ,查找速度快, 第三 字典 占用内存是比较大的。第四 ,字典是无序的, 这点和tuple 是完全不一样的。




分享快乐,留住感动。    Mon Nov 06 16:25:57 2017   ---biaoge



  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
collections是Python内置库的一个模块,它提供了一些有用的类,用于处理Python的集合类型。这些类包括:Counter、defaultdict、deque、namedtuple等。 1. Counter类 Counter类是一个用于计数的容器,它可以统计元素出现的次数。可以使用它来创建一个字典,其字典的键是元素,值是元素的数量。Counter类的用法如下: ```python from collections import Counter # 创建一个Counter对象 c = Counter(['a', 'b', 'c', 'a', 'b', 'a']) # 统计元素出现的次数 print(c) # Counter({'a': 3, 'b': 2, 'c': 1}) # 统计前n个出现次数最多的元素 print(c.most_common(2)) # [('a', 3), ('b', 2)] ``` 2. defaultdict类 defaultdict类是一个字典类型,它可以自动为不存在的键分配一个默认值。当使用一个不存在的键时,它会自动创建一个默认值,并返回它。defaultdict类的用法如下: ```python from collections import defaultdict # 创建一个defaultdict对象 d = defaultdict(int) # 添加键值对 d['a'] = 1 d['b'] = 2 # 访问不存在的键 print(d['c']) # 0 ``` 3. deque类 deque类是一个双向队列,它可以在队列的两端进行插入和删除操作。deque类的用法如下: ```python from collections import deque # 创建一个deque对象 d = deque() # 在队列的左边插入元素 d.appendleft(1) d.appendleft(2) # 在队列的右边插入元素 d.append(3) d.append(4) # 访问队列的元素 print(d) # deque([2, 1, 3, 4]) # 从队列的左边删除元素 print(d.popleft()) # 2 # 从队列的右边删除元素 print(d.pop()) # 4 ``` 4. namedtuplenamedtuple类是一个工厂函数,它可以用来创建一个具有字段名的元组。该类返回的是一个元组子类,它可以像普通元组一样访问元素,但也可以使用字段名来访问元素。namedtuple类的用法如下: ```python from collections import namedtuple # 定义一个namedtuple类型 Point = namedtuple('Point', ['x', 'y']) # 创建一个Point对象 p = Point(1, 2) # 访问元素 print(p.x) # 1 print(p.y) # 2 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值