第六章 定制数据对象 打包代码和数据
摘要:python字典:允许有效的组织数据,将数据与名关联而不是与数字关联,从而实现快速查找。当python的内置数据结构无法胜任时,python class语句还允许定义自己的数据结构。
书中文件的下载地址:http://python.itcarlow.ie/resources.html
1、列表查询
从教练的原始数据中抽取并处理Sarah的3个最快时间
#创建函数,对时间格式进行清理
def sanitize(time_string):
#in操作符检查字符是否包含一个短横线与冒号
if '-' in time_string:
spliter='-'
elif':' in time_string:
spliter=':'
else:
#如果字符串不需要清理,就什么也不做
return(time_string)
#分解字符串,抽出分钟和秒部分
(mins,secs)=time_string.split(spliter)
return(mins+'.'+secs)
#创建新函数,接受一个文件名作为唯一的参数
def get_coach_data(filename):
#增加异常处理代码
try:
#打开文件,读取数据
with open(filename)as f:
data=f.readline()
#将数据返回代码之前先对数据完成分解、去除空白符处理
return(data.strip().split(','))
except IOError as ioerr:
#通知用户有错误(如果出现错误),并返回“None”来提示失败
print('File error:'+str(ioerr))
return(None)
#调用函数,将sarah数据传输为一个列表,赋至到“sarah”变量
sarah=get_coach_data('sarah2.txt')
#pop(0)调用将删除并返回列表最前面的数据项,两个pop(0)调用则会删除前两个数据值,并把它们赋给指定的变量
(sarah_name,sarah_dob)=sarah.pop(0),sarah.pop(0)
print(sarah_name+"'s fastest time are:"+str(sorted(set([sanitize(t) for t in sarah]))[0:3]))
2、使用字典关联数据
字典:是一个内置的数据结构,允许将数据与键不是数字关联,这样可以使内存中的数据与实际数据的结构一致。注重数据的结构。
- dict():工厂函数或者使用{}可以创建一个空字典。
- 访问一个名为person的字典与键Name关联的值,可以使用person['Name']
- 类似于列表和集合,python的字典会随着新数据增加到这个数据结构而动态扩大
#调用函数,将sarah数据传输为一个列表,赋至到“sarah”变量
sarah=get_coach_data('sarah2.txt')
#创建一个空字典
sarah_data={}
#通过文件数据与字典键关联来填充字典
sarah_data['Name']=sarah.pop(0)
sarah_data['DOB']=sarah.pop(0)
sarah_data['Times']=sarah
#处理数据引用字典
print(sarah_data['Name']+"'s fastest times are:"+str(sorted(set([sanitize(t) for t in sarah_data['Times']]))[0:3]))
改进代码
- 一次性完成订单的创建
- 将字典创建代码移动到get_coach_data()函数中,返回一个字典而不是列表
- 把确定选手最快的3个时间的代码也移到get_coach_data()函数中
- 调整主代码中的函数调用,调用新的get_coach_data()函数中
#创建新函数,接受一个文件名作为唯一的参数
def get_coach_data(filename):
#增加异常处理代码
try:
#打开文件,读取数据
with open(filename)as f:
data=f.readline()
#在一次性创建字典之前,创建一个临时列表存放数据
temp1=data.strip().split(',')
#字典创建代码和确认前3时间成为函数的一部分
return({'Name':temp1.pop(0),
'DOB':temp1.pop(0),
'Times':str(sorted(set([sanitize(t) for t in temp1]))[0:3])})
except IOError as ioerr:
#通知用户有错误(如果出现错误),并返回“None”来提示失败
print('File error:'+str(ioerr))
return(None)
#调用函数
james=get_coach_data('james2.txt')
print(james['Name']+"'s fastest times are:"+james['Times'])
3、定制类
定制代码与定制数据相关联-将代码及其数据打包在类中
实例中的方法相同,属性(数据)不同;方法共享,属性不共享,self代码帮助标识要处理哪个对象实例的数据。
定义一个类,实际上在定义一个工厂函数,在代码中使用工厂函数创建实例
self-方法参数,总是指向当前对象实例
- 用class关键字定义一个类
- 类方法(代码)与函数的定义基本相同,用def关键词定义
- 类属性(数据)就是对象实例中的变量
- 在类中定义__init__()方法来初始化实例
- 类中定义的每个方法都必须提供self作为第一个参数
- 类中的每个属性前面都必须有self,从而将数据与其实例关联。
class Athlete:
def __init__(self,a_name,a_dob=None,a_times=[]):
self.name=a_name
self.dob=a_dob
self.times=a_times
def top3(self):
return(sorted(set([sanitize(t) for t in self.times]))[0:3])
#将提供的参数追加到现有的计时值列表
def add_time(self,time_value):
self.times.append(time_value)
#用提供的参数列表扩展现有的计时值列表
def add_times(self,list_of_times):
self.times.extend(list_of_times)
#创建新函数,接受一个文件名作为唯一的参数
def get_coach_data(filename):
#增加异常处理代码
try:
#打开文件,读取数据
with open(filename)as f:
data=f.readline()
#创建一个临时列表存放数据
temp1=data.strip().split(',')
#替换为Athlete对象创建代码
return (Athlete(temp1.pop(0),temp1.pop(0),temp1))
except IOError as ioerr:
#通知用户有错误(如果出现错误),并返回“None”来提示失败
print('File error:'+str(ioerr))
return(None)
#调用函数
james=get_coach_data('james2.txt')
#使用点记法访问数据,调用top3方法,转换为字符串
print(james.name+"'s fastest times are:"+str(james.top3()))
4、继承类
将类建立在内置功能上
- 类可以从零开始构建,也可以从python的内置类或者其它定制类中继承
- 类可以放在一个python模块中
#继承内置的List类
class AthleteList(list):
def __init__(self,a_name,a_dob=None,a_times=[ ]):
list.__init__([])
self.name=a_name
self.dob=a_dob
#数据本身是计时数据,不需要“times”属性
self.extend(a_times)
def top3(self):
return(sorted(set([sanitize(t) for t in self]))[0:3])
vera=AthleteList('Vera Vi')
#从内置的List继承,所以可以使用List方法来完成
vera.append('1.31')
print(vera.top3())
vera.extend(['2.22','1_21','2:22'])
print(vera.top3())
#创建新函数,接受一个文件名作为唯一的参数
def get_coach_data(filename):
#增加异常处理代码
try:
#打开文件,读取数据
with open(filename)as f:
data=f.readline()
#创建一个临时列表存放数据
temp1=data.strip().split(',')
#替换为Athlete对象创建代码
return (AthleteList(temp1.pop(0),temp1.pop(0),temp1))
except IOError as ioerr:
#通知用户有错误(如果出现错误),并返回“None”来提示失败
print('File error:'+str(ioerr))
return(None)
#调用函数
james=get_coach_data('james2.txt')
#使用点记法访问数据,调用top3方法,转换为字符串
print(james.name+"'s fastest times are:"+str(james.top3()))