定制数据对象

1、字典

在上一篇中我们看到数据处理似乎并不是很难的事情,但我们考虑的只是非常简单的情形,所有数据都可以转为同一类型处理。实际中,会有一些文件包含各种类型的数据,而且数据具有结构性,这时候用列表处理数据就不太方便了,比如:

>>> with open('james2.txt') as jaf2:
    data=jaf2.readline()
    print(data)

James Lee,2002-3-14,2-34,3:21,2.34,2.45,3.01,2:01,2:01,3:10,2-22,2-01,2.01,2:16

我们看到,数据第一项是名字,第二项是生日,之后是跑步成绩。我们将如何构建数据的关联性呢?我们先来看一下字典的用法:

#以下两种方式都可以创建空字典
>>> cleese={}
>>> palin=dict()
>>> type(cleese)

>>> type(palin)

#以下两种方式都可以将键与值关联
>>> cleese['Name']='John Cleese'
>>> cleese['Occupations']=['actor','comedian','writer','film producter']
>>> palin={'Name':'Michael Palin','Occupations':['comedian','actor','writer','tv']}
>>> cleese['Name']
'John Cleese'
>>> cleese['Occupations'][-1]
'film producter'

然后我们用字典来找出运动员前三快的成绩:

>>> def get_coach_data(filename):
    try:
        with open(filename) as f:
            data=f.readline()
        templ=data.strip().split(',')
        return({'Name':templ.pop(0),
            'Dob':templ.pop(0),
            'Times':str(sorted(set([sanitize(t) for t in templ]))[0:3])})
    except IOerror as err:
        print('File error: '+str(err))
        return(None)

    
>>> james=get_coach_data('james2.txt')
>>> print(james['Name']+" 's fastest times are: "+james['Times'])
James Lee 's fastest times are: ['2.01', '2.16', '2.22']

2、类

Python使用class创建对象。每个类都有一个特殊方法,名为__init__(),可以通过这个方法控制如何初始化对象。另外,类中所有方法的第一个参数都是self,实际上self标识了要处理的对象实例。我们依然以运动员为例:

>>> class Athlete:
    def __init__(self,name,dob=None,times=[]):
        self.name=name
        self.dob=dob
        self.times=times
        
    def top3(self):
        return(sorted(set([sanitize(t) for t in self.times]))[0:3])

    
>>> def get_coach_data(filename):
    try:
        with open(filename) as f:
            data=f.readline()
        templ=data.strip().split(',')
        return(Athlete(templ.pop(0),templ.pop(0),templ))
    except IOError as err:
        print('File error: '+str(err))
        return(None)

>>> james=get_coach_data('james2.txt')
>>> print(james.name+" 's fastest times are: "+str(james.top3()))
James Lee 's fastest times are: ['2.01', '2.16', '2.22']

有了类,我们还可以很方便的做很多其它的事,比如我现在有新的跑步成绩数据需要加入,那么我们就可以通过为类增加一个方法来解决:

>>> class Athlete:
    def __init__(self,name,dob=None,times=[]):
        self.name=name
        self.dob=dob
        self.times=times
        
    def top3(self):
        return(sorted(set([sanitize(t) for t in self.times]))[0:3])
    def add_times(self,time):
        self.times.extend(time)

        
>>> vere=Athlete('Vere Vi')
>>> vere.add_times(['1.31','1-21','2.22','2.25'])
>>> print(vere.top3())
['1.21', '1.31', '2.22']

这样看来,我们有什么新的需求,在类中添加新方法就万事大吉了,然而我们看一下add_times方法,它本质上就是列表的extend()方法啊,我们这里还要重新写一遍,不能直接用吗?这就涉及到偷懒的办法:继承。实际上如果我们的类是现有类(比如list)的继承,那么继承类可以直接使用父类所有方法,这非常方便。

#新类派生括号中的类
>>> class AthleteList(list):
    def __init__(self,name,dob=None,times=[]):
        list.__init__([])
        self.name=name
        self.dob=dob
        self.extend(times)
        
    def top3(self):
        #这里self.times变成了self,因为self本身就是计时数据列表
        return(sorted(set([sanitize(t) for t in self]))[0:3])

    
>>> vere=AthleteList('Vere Vi')
>>> vere.extend(['1.31','1-21','2.22','2.25'])
>>> print(vere.top3())
['1.21', '1.31', '2.22']

通过继承我们可以直接使用list类的方法extend()来操作我们的AthleteList对象了,不止如此,我们还可以用列表的其它方法。

你可能感兴趣的:(定制数据对象)