python模块介绍- collections(4)-namdedtuple 命名元组

长平狐 发布于 2013/12/25 17:23
阅读 366
收藏 0

python模块介绍- collections(4)-namdedtuple 命名元组

2013-04-17 磁针石

#承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.com qq 37391319 博客:http://blog.csdn.net/oychw

#版权所有,转载刊登请来函联系

#深圳测试自动化python项目接单群113938272深圳会计软件测试兼职 6089740

#深圳地摊群 66250781武冈洞口城步新宁乡情群49494279

#自动化测试和python群组: http://groups.google.com/group/automation_testing_python

#参考资料:《The Python Standard Libraryby Example 2011》

1.3.4 namedtuple

命名元组和普通元组的的内存效率差不多。它不会针对每个实例生成字典。

import collections

 

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

 

print 'Type of Person:', type(Person)

 

bob = Person(name='Bob', age=30, gender='male')

print '\nRepresentation:', bob

 

jane = Person(name='Jane', age=29, gender='female')

print '\nField by name:', jane.name

 

print '\nFields by index:'

for p in [ bob, jane ]:

    print '%s is a %dyear old %s' % p

执行结果:

# ./collections_namedtuple_person.py

Type of Person: <type 'type'>

 

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

 

Field by name: Jane

 

Fields by index:

Bob is a 30 year old male

Jane is a 29 year old female

从上例可以看出命名元组Person类和excel的表头类似,给下面的每个列取个名字,真正excel行数据则存储在Person类的实例中。好处在于可以jane.name这样的形式访问,比记元组的index要直观。

注意列名在实现内部其实是个标识符,所以不能和关键字冲突,只能用字母或者下划线开头。下例会报错:

import collections

 

try:

    collections.namedtuple('Person','name class age gender')

except ValueError, err:

    print err

 

try:

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

except ValueError, err:

    print err

 执行结果:

# ./collections_namedtuple_bad_fields.py

Type names and field names cannot be a keyword: 'class'

Encountered duplicate field name: 'age'

 

设置rename=True,列名会在冲突时自动重命名,不过这种重命名并不美观。

import collections

 

with_class = collections.namedtuple(

    'Person', 'nameclass age gender',

    rename=True)

print with_class._fields

 

two_ages = collections.namedtuple(

    'Person', 'name agegender age',

    rename=True)

print two_ages._fields

执行结果:

# ./collections_namedtuple_rename.py

('name', '_1', 'age', 'gender')

('name', 'age', 'gender', '_3')

 

定义:

collections.namedtuple(typename, field_names[,verbose=False][, rename=False])

返回一个命名元组类。如果verbose为True,会打印类定义信息

             

              命名元组在处理数据库的时候比较有用:

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, paygradeFROM employees')

for emp in map(EmployeeRecord._make, cursor.fetchall()):

    print emp.name, emp.title

              方法:

           classmethod somenamedtuple._make(iterable)

           根据序列或者迭代生成新实例,比如:

>>> t = [11, 22]

>>> Point._make(t)

Point(x=11, y=22)

                               somenamedtuple._asdict()

                               返回有序字典形式,比如:

>>> p._asdict()

OrderedDict([('x', 11), ('y', 22)])

                               somenamedtuple._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())

somenamedtuple._fields :

返回field元组,在创建更复杂的命名元组时有用:

>>> p._fields            # view the field names

('x', 'y')

 

>>> Color = namedtuple('Color', 'redgreen 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)

 

              其他:

                      可以使用getattr获取属性:

>>> getattr(p, 'x')

11

                转换字典为命名元组:

>>> d = {'x': 11, 'y': 22}

>>> Point(**d)

Point(x=11, y=22)

                修改类属性,比如定制输出格式:

>>>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

添加新field:

Point3D = namedtuple('Point3D', Point._fields+ ('z',))

设置默认值:

>>> Account = namedtuple('Account','owner balance transaction_count')

>>> default_account = Account('<ownername>', 0.0, 0)

>>> johns_account = default_account._replace(owner='John')

设置Enumerated:

>>> Status = namedtuple('Status','open pending closed')._make(range(3))

>>> Status.open, Status.pending,Status.closed

(0, 1, 2)

>>> class Status:

       open, pending, closed = range(3)



原文链接:http://blog.csdn.net/oychw/article/details/8813204
加载中
返回顶部
顶部