当先锋百科网

首页 1 2 3 4 5 6 7

第四章 持久存储

1、程序生成数据

strip():从字符串中去除不想要的空白符

man=[]
other=[]
try:
	data=open('sketch.txt')
	for each_line in data:
		try:
			(role,line_spoken)=each_line.split(':',1)
#strip()删除line_spoken变量中不需要的空白符
#将去除空白符后的字符串再赋回到自身
			line_spoken=line_spoken.strip()
#根据role的值将line_spoken增加到适当的列表中
			if role=='Man':
				man.append(line_spoken)
			elif role=='Other Man':
				other.append(line_spoken)
		except ValueError:
			pass
	data.close()
except IOError:
	print('The datafile is missing!')
#输出各个列表
print(man)
print(other)

2、以写模式打开文件

Print()的file参数控制将数据发送/保存到哪里

try:
    #打开两个文件,分别赋到一个文件对象
    man_file=open('man_data.txt','w')
    other_file=open('other_data.txt','w')
    #使用print将指定的列表保存到指定的磁盘文件
    print(man,file=man_file)
    print(other,file=other_file)

    man_file.close()
    other_file.close()
except IOError:
    print('File error.')
  • IOError会导致数据被破坏,确保关闭文件。

finally组总会执行,不论try/except语句出现异常

try:
    #打开两个文件,分别赋到一个文件对象
    man_file=open('man_data.txt','w')
    other_file=open('other_data.txt','w')
    #使用print将指定的列表保存到指定的磁盘文件
    print(man,file=man_file)
    print(other,file=other_file)

except IOError:
    print('File error.')

finally:
    #把close调用移到最后,减少数据破坏错误的可能性,确保文件妥善的关闭
    man_file.close()
    other_file.close()
  • 如何发现错误的特定信息

python变量只包含数据对象的一个引用,python中的字符串不可变,元祖为不可变的列表,所有的数据类型都不可变。原来的数据不能改变,还有其他的变量指向它,永远不可能知道还有哪些变量指向某个特定的字符串

locals()返回当前作用域内定义的所有名的一个集合。

except组传入一个异常对象,并使用as关键字赋到一个标识符

str():访问任何数据对象(支持串转换)的串表示

in操作符用于检查成员关系

“+”操作符:用于字符串时将联结两个字符串,用于数字时将两个数相加

 try:
	data=open('missing.txt')
	print(data.readline(),end='')
#为异常对象给定一个名
except IOError as err:
	#使用str()要求异常对象表现为一个字符串
	print('File error:'+str(err))
finally:
	#in操作符测试成员关系
	if 'data' in locals():
		#在locals返回的集合中搜索字符串data,找到,则文件成功打开,没有找到,安全调用close()方法。
		data.close()

File error:[Errno 2] No such file or directory: 'missing.txt'

  • 用with处理文件

with语句利用了一种名为上下文管理协议的python技术,自动处理所有已打开文件的关闭工作,即使出现异常也不例外,也使用as关键字

try:
    #打开两个文件,分别赋到一个文件对象
    man_file=open('man_data.txt','w')
    other_file=open('other_data.txt','w')
    #使用print将指定的列表保存到指定的磁盘文件
    print(man,file=man_file)
    print(other,file=other_file)

except IOError as err:
    print('File error:'+str(err))

finally:
    #把close调用移到最后,减少数据破坏错误的可能性,确保文件妥善的关闭
    if 'man_file' in the locals():
        man_file.close()
    if 'other_file' in the locals():
        other_file.close()
  • with模式
try:
    with open('man_data.txt','w') as man_file:
        print(man,file=man_file)
    with open('other_data.txt','w') as other_file:
        print(other,file=other_file)
except IOError as err:
    print('File error:'+str(err))

print()会模仿python解释器实际存储列表数据的格式来显示数据,展示数据在内存中的“样子”

  • 解析数据格式
  • 定制代码

标准输出:sys.stdout

print_lol()第四个参数:标识把数据写入哪个位置,一定要为参数提供一个缺省值sys.stdout。这样如果调用这个函数没有指定文件对象,则会依然写至屏幕。

import sys
def print_lol(the_list,indent=False,level=0,fn=sys.stdout):
	for each_item in the_list:
		if isinstance(each_item,list):
			print_lol(each_item,indent,level+1,fn)
		else:
			if indent:
				for tab_stop in range(level):
					print("t",end='',file=fn)
			print(each_item,file=fn)
import nester
try:
    with open('man_data.txt','w') as man_file:
        nester.print_lol(man,file=man_file)
    with open('other_data.txt','w') as other_file:
        nester.print_lol(other,file=other_file)
except IOError as err:
    print('File error:'+str(err))
  • “腌制数据”

pickle库:保存和加载几乎任何python数据对象,包括列表。dump()保存数据,load()恢复数据,必须以二进制访问模式打开文件。高效的保存和恢复数据的机制,保存到磁盘和磁盘恢复。

import pickle
try:
        #将访问模式改为“可写二进制模式”,调用替换为“pickle”
    with open('man_data.txt','wb') as man_file, open('other_data.txt','wb') as other_file:
        pickle.dump(man,file=man_file)
        pickle.dump(other,file=other_file)
except IOError as err:
    print('File error:'+str(err))
#pickle接触数据腌制时出现的异常
except pickle.PickleError as perr:
        print('Pickle error:'+str(perr))
  • 使用pickle的通用文件I/O

第5章 推导数据 处理数据

  • 从各个文件将数据读入各自的列表

方法串链:data.strip().split(),strip应用到data中的数据行,去除不想要的空白符,split创建一个列表,得到的列表应用到以上代码的目标标识符。从左到右读

#打开文件
with open('james.txt')as jaf:
    #读数据行
    data=jaf.readline()
#将数据转换为一个列表
james=data.strip().split(',')
with open('julie.txt') as juf:
    data=juf.readline()
julie=data.strip().split(',')
with open('mikey.txt') as mif:
    data=mif.readline()
mikey=data.strip().split(',')
with open('sarah.txt')as saf:
    data=saf.readline()
sarah=data.strip().split(',')

print(james)
print(julie)
print(mikey)
print(sarah)

cbde95fddffa876c960c512aaba44481.png
  • 排序

原地排序:sort(),排序后的数据替换原来的数据

复制排序:sorted(),原数据的顺序依然保留

默认升序,降序可以传入参数reverse=True

  • 函数串链 从右到左读
#打开文件
with open('james.txt')as jaf:
    #读数据行
    data=jaf.readline()
#将数据转换为一个列表
james=data.strip().split(',')
with open('julie.txt') as juf:
    data=juf.readline()
julie=data.strip().split(',')
with open('mikey.txt') as mif:
    data=mif.readline()
mikey=data.strip().split(',')
with open('sarah.txt')as saf:
    data=saf.readline()
sarah=data.strip().split(',')

#创建函数,对时间格式进行清理
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)


#创建4个开始为空的新列表
clean_james=[]
clean_julie=[]
clean_mikey=[]
clean_sarah=[]

#取原列表中的各个数据项进行清理,然后将清理后的列表追加到适当的列表
for each_t in james:
    clean_james.append(sanitize(each_t))
for each_t in julie:
    clean_julie.append(sanitize(each_t))
for each_t in mikey:
    clean_mikey.append(sanitize(each_t))
for each_t in sarah:
    clean_sarah.append(sanitize(each_t))
#输出已经清理后的新列表
print(sorted(clean_james))
print(sorted(clean_julie))
print(sorted(clean_mikey))
print(sorted(clean_sarah))

e4acc82e7a0d4e84b4f205dce23b2fa4.png
  • 列表推导 简化重复代码:

列表推导:list comprehension 减少将一个列表转换为另一个列表时编写的代码,支持函数编程概念的一个例子

从一个代码转换为另一个列表需要:

  • 创建一个新列表存放转换后的数据
  • 迭代处理原列表中的每个数据项
  • 每次迭代后完成转换
  • 将转换后的数据追加到新列表

8db2826c4cc67242b4816ad4b04d9def.png

be013f8d5978eae8136e84847ffffb06.png
#打开文件
with open('james.txt')as jaf:
    #读数据行
    data=jaf.readline()
#将数据转换为一个列表
james=data.strip().split(',')
with open('julie.txt') as juf:
    data=juf.readline()
julie=data.strip().split(',')
with open('mikey.txt') as mif:
    data=mif.readline()
mikey=data.strip().split(',')
with open('sarah.txt')as saf:
    data=saf.readline()
sarah=data.strip().split(',')

#创建函数,对时间格式进行清理
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)

#列表推导完成转换,再利用sorted()对新列表进行排序
print(sorted([sanitize(t) for t in james]))
print(sorted([sanitize(t) for t in julie]))
print(sorted([sanitize(t) for t in mikey]))
print(sorted([sanitize(t) for t in sarah]))
  • 迭代删除重复项

像是一个过滤器,重复项删除过滤器需要在列表创建过程中检查所创建的列表

#把无序且不一致的数据替换为经过清理的有序副本
james=sorted([sanitize(t) for t in james])
julie=sorted([sanitize(t) for t in julie])
mikey=sorted([sanitize(t) for t in mikey])
sarah=sorted([sanitize(t) for t in sarah])

#创建空列表,存放唯一的数据项
unique_james=[]
#在现有数据上迭代处理
for each_t in james:
    #如果数据项不在新列表中,追加到列表中
    if each_t not in unique_james:
        unique_james.append(each_t)
#从列表分片中得到前3个数据项
print(unique_james[0:3])

unique_julie=[]
for each_t in julie:
    if each_t not in unique_julie:
        unique_julie.append(each_t)
print(unique_julie[0:3])

unique_mikey=[]
for each_t in mikey:
    if each_t not in unique_mikey:
        unique_mikey.append(each_t)
print(unique_mikey[0:3])

unique_sarah=[]
for each_t in sarah:
    if each_t not in unique_sarah:
        unique_sarah.append(each_t)
print(unique_sarah[0:3])

b9866c0d259e49f841ca5670507e5bcb.png
  • 用集合删除重复项

集合中的数据项是无序的,不允许重复。

工厂函数:用于创建某个类型的新的数据项,set()创建一个新的集合,数据列表中的任何重复项都会被忽略。

#创建函数,对时间格式进行清理
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=get_coach_data('sarah.txt')
james=get_coach_data('james.txt')
julie=get_coach_data('julie.txt')                       
mikey=get_coach_data('mikey.txt')

#对sorted形成的列表进行分片,解决重复项问题
print(sorted(set([sanitize(t) for t in james]))[0:3])
print(sorted(set([sanitize(t) for t in julie]))[0:3])                        
print(sorted(set([sanitize(t) for t in mikey]))[0:3])
print(sorted(set([sanitize(t) for t in sarah]))[0:3])