+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2019-07(3)

2019-08(115)

2019-09(109)

2019-10(10)

2019-11(7)

collections模块——namedtuple

发布于2020-10-17 21:03     阅读(488)     评论(0)     点赞(13)     收藏(5)


0

1

2

3

4

5

6

namedtuple —— Tuple Subclass with Named Fields

标准的tuple采用索引来访问成员

bob = ('Bob', 30, 'male')
print('Representation:', bob)

jane = ('Jane', 29, 'female')
print('\nField by index:', jane[0])

print('\nFields by index:')
for p in [bob, jane]:
    print('{} is a {} year old {}'.format(*p))

对于简单的使用,这很方便

Representation: ('Bob', 30, 'male')

Field by index: Jane

Fields by index:
Bob is a 30 year old male
Jane is a 29 year old female

相反,记住应为每个值使用哪个索引可能会导致错误,尤其是在元组具有很多字段并且构造远离它的地方的情况下。 namedtuple为每个成员分配名称以及数字索引。

Defining

namedtuple实例的存储效率与常规元组一样,因为它们没有按实例的字典。每种namedtuple都由其自己的类表示,该类是使用namedtuple()工厂函数创建的。参数是新类的名称和包含元素名称的字符串。

import collections

Person = collections.namedtuple('Person', 'name age')

bob = Person(name='Bob', age=30)
print('\nRepresentation:', bob)

jane = Person(name='Jane', age=29)
print('\nField by name:', jane.name)

print('\nFields by index:')
for p in [bob, jane]:
    print('{} is {} years old'.format(*p))

如示例所示,可以使用点分符号(obj.attr)以及使用标准元组的位置索引来按名称访问namedtuple的字段。

Representation: Person(name='Bob', age=30)

Field by name: Jane

Fields by index:
Bob is 30 years old
Jane is 29 years old

就像常规元组一样,namedtuple是不可变的。此限制允许元组实例具有一致的哈希值,这使得可以将它们用作字典中的键并包含在集合中。

import collections

Person = collections.namedtuple('Person', 'name age')

pat = Person(name='Pat', age=12)
print('\nRepresentation:', pat)

pat.age = 21

尝试通过其命名属性更改值会导致AttributeError。

Representation: Person(name='Pat', age=12)
Traceback (most recent call last):
  File "collections_namedtuple_immutable.py", line 17, in
<module>
    pat.age = 21
AttributeError: can't set attribute

Invalid Field Names

如果字段名重复或与Python关键字冲突,则字段名无效。

import collections

try:
    collections.namedtuple('Person', 'name class age')
except ValueError as err:
    print(err)

try:
    collections.namedtuple('Person', 'name age age')
except ValueError as err:
    print(err)

解析字段名称时,无效值会导致ValueError异常。

Type names and field names cannot be a keyword: 'class'
Encountered duplicate field name: 'age'

在基于程序控制范围之外的值创建namedtuple的情况下(例如代表数据库查询返回的行,而该模式事先未知),重命名选项应设置为True,这样无效字段被重命名。

import collections

with_class = collections.namedtuple(
    'Person', 'name class age',
    rename=True)
print(with_class._fields)

two_ages = collections.namedtuple(
    'Person', 'name age age',
    rename=True)
print(two_ages._fields)

重命名字段的新名称取决于它们在元组中的索引,因此名称类的字段将变为_1,而重复年龄字段将更改为_2。

('name', '_1', 'age')
('name', 'age', '_2')

Special Attributes

namedtuple提供了一些有用的属性和方法来处理子类和实例。所有这些内置属性的名称都带有下划线()前缀,按照惯例,在大多数Python程序中,下划线()表示私有属性。但是,对于namedtuple,该前缀旨在防止该名称与用户提供的属性名称冲突。
传递给namedtuple定义新类的字段名称保存在_fields属性中。

import collections

Person = collections.namedtuple('Person', 'name age')

bob = Person(name='Bob', age=30)
print('Representation:', bob)
print('Fields:', bob._fields)

尽管参数是一个用空格分隔的字符串,但是存储的值是各个名称的序列。

Representation: Person(name='Bob', age=30)
Fields: ('name', 'age')

可以使用_asdict()将namedtuple实例转换为OrderedDict实例。

import collections

Person = collections.namedtuple('Person', 'name age')

bob = Person(name='Bob', age=30)
print('Representation:', bob)
print('As Dictionary:', bob._asdict())

OrderedDict的键与namedtuple的字段的顺序相同。

Representation: Person(name='Bob', age=30)
As Dictionary: OrderedDict([('name', 'Bob'), ('age', 30)])

_replace()方法将构建一个新实例,替换流程中某些字段的值。

import collections

Person = collections.namedtuple('Person', 'name age')

bob = Person(name='Bob', age=30)
print('\nBefore:', bob)
bob2 = bob._replace(name='Robert')
print('After:', bob2)
print('Same?:', bob is bob2)

尽管名称暗示它正在修改现有对象,但是由于namedtuple实例是不可变的,因此该方法实际上返回了一个新对象。

Before: Person(name='Bob', age=30)
After: Person(name='Robert', age=30)
Same?: False

原文链接:https://blog.csdn.net/weixin_44144300/article/details/109111917

0

1

2

3

4

5



所属网站分类: 技术文章 > 博客

作者:大哥别打我

链接: https://www.pythonheidong.com/blog/article/594549/6e39736b449d4ec47e9c/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

13 0
收藏该文
已收藏

评论内容:(最多支持255个字符)