zoukankan      html  css  js  c++  java
  • 第四章:持久存储

    程序处理文件以后一般不会丢弃而是存储在磁盘

    修改上一章的代码满足一下要求

    1,创建一个空列表为man

    2,创建一个空列表为other

    3,增加一行代码,删除line_spoken中的空格及回车

    4,给出条件和代码,根据role值将line_spoken增加到适当的列中

    5,在屏幕上面输出man和other列表

    vim sketch-1.py

    man = []
    other = []    #新建两个空列表
    data = open('sketch.txt') #打开文件
    for each_line in data:    #按行迭代
            try:              #和except一起忽略代码的指定错误
                    (role,line_spoken) = each_line.split(':',1)     #使用符号:分割列成为一个元祖赋值给role和line_spoken分别代表人物和说的话
                    line_spoken = line_spoken.strip()               #使用strip()函数去掉空格和回车
    
                    if role == 'Man':                               #判断假如人物是Man,将他说的话用apppend方法追加到man列表
                            man.append(line_spoken)
                    else:
                            other.append(line_spoken)               #将其他人说的话追加到other列表
            except ValueError:
                    pass
    print man
    print other
    data.close()
    

      运行结果

     

    以上只是把两个说的户输出到屏幕,下面修改代码使其存储到文件中

    vim sketch-2.py

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    man = []
    other = []    #新建两个空列表
    data = open('sketch.txt') #打开文件
    for each_line in data:    #按行迭代
            try:              #和except一起忽略代码的指定错误
                    (role,line_spoken) = each_line.split(':',1)     #使用符号:分割列成为一个元祖赋值给role和line_spoken分别代表人物和说的话
                    line_spoken = line_spoken.strip()               #使用strip()函数去掉空格和回车
    
                    if role == 'Man':                               #判断假如人物是Man,将他说的话用apppend方法追加到man列表
                            man.append(line_spoken)
                    else:
                            other.append(line_spoken)               #将其他人说的话追加到other列表
            except ValueError:
                    pass
    data.close() #print man #print other try: man_file = open('man_data.txt','w') other_file = open('other_data.txt','w') # print (man,file=man_file) # print (other,file=other_file) #按书里的这语法会报错可能是python3的语法 man_file.write(' '.join(man)) other_file.write(' '.join(other)) #写文件,需要是字符串格式使用join转换 man_file.close() other_file.close() except IOError: print ('File error') ~

     在当前文件夹生成两个文件记录内容

    man_data.txt
    other_data.txt

    PS:如果只是从文件读取数据得到一个IOError确实很烦人,不过还不算危险,因为数据还在文件中,只是得到这些数据有些麻烦

    向文件写数据就完全不一样了,如果文件在关闭前出现一个IOError,所写的数据可能会被破坏,而且只有在这种情况发生了才知道

    否则根本无法了解这一点。假如以上代码

    other_file.write(' '.join(other))出现问题一下的关闭操作不会执行,这里有一个策略保证无论是否出现错误都能运行某些代码
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    man = []
    other = []    #新建两个空列表
    data = open('sketch.txt') #打开文件
    for each_line in data:    #按行迭代
            try:              #和except一起忽略代码的指定错误
                    (role,line_spoken) = each_line.split(':',1)     #使用符号:分割列成为一个元祖赋值给role和line_spoken分别代表人物和说的话
                    line_spoken = line_spoken.strip()               #使用strip()函数去掉空格和回车
    
                    if role == 'Man':                               #判断假如人物是Man,将他说的话用apppend方法追加到man列表
                            man.append(line_spoken)
                    else:
                            other.append(line_spoken)               #将其他人说的话追加到other列表
            except ValueError:
                    pass
    data.close()
    #print man
    #print other
    try:
            man_file   = open('man_data.txt','w')
            other_file = open('other_data.txt','w')
    #       print (man,file=man_file)
    #       print (other,file=other_file)                   #按书里的这语法会报错可能是python3的语法
            man_file.write(' '.join(man))
            other_file.write(' '.join(other))               #写文件,需要是字符串格式使用join转换
    except IOError:
            print ('File error')
    finally:
            man_file.close()            
            other_file.close()                                   #不管是否出现错误都会执行关闭
    

    不论出现什么情况finally下的代码都会执行。可以减少数据破坏的可能性,这是一个很大的改进,可以确保文件妥善的关闭

    知道错误类型还不够

    出现文件IO错误时候,代码一般会先一个file error,太过于一般化了因为有几种可能

    1,文件无法打开

    2,可以打开但是无法x写入

    3,可能是一个权限错误,或者磁盘满了

    谁知道呢 ,看起来python解释器知道,运行时出现错误python会产生一个特定类型的异常,会创建一个异常对象,它会作为一个参数传递

    except代码组

    看一下例子,试着打开一个不存在的文件,File error是错误消息,NameError这个异常导致了代码  

     崩溃,文件不存在就不能在数据对象调用close()方法。一种简单的修正方法是对finally组增加一个

    简单的测试,尝试调用close()之前先查看data名是否存在。locals()BIF会返回当前作用域中定义

    的所有名的一个集合,只有在安全时候才调用close()

     

    这里会在locals()BIF返回的集合中搜索字符串data如果有代表文件安全打开可以调用close,所以只提示是File error错误

    不过还是不清楚到底什么导致了这个错误

    产生的异常由except组处理时,Python解释器将一个异常对象传入这个except组。只需要做一个很小的修改就可以在代码中使用这个异常

     vim sketch-3.py

    try:
        data = open('miss.txt')
        print data.readline(),
    except IOError as err:          #为异常对象取一个名
        print 'File error' + err    #作为错误消息输出
    finally:
        if 'data' in locals():
                data.close()
    

      运行还是报错TypeError

    是以为异常对象和字符串不兼容,使用str()转换成字符串

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    try:
        data = open('miss.txt')
        print data.readline(),
    except IOError as err:          #为异常对象取一个名
        print 'File error' + str(err)       #作为错误消息输出
    finally:
        if 'data' in locals():
                data.close()
    

     运行输出了正确的错误提示

     

     用with处理文件

    由于处理文件时使用模式try/except/finally模式相当有用,所以python提供了一个语句抽象

    出相关的一些细节。对文件使用with语句可以大大减少需要编写的代码量,因为有了with语句

    不再需要包含一个finally组来处理文件的关闭

    vim sketch-5.py

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    man = []
    other = []    #新建两个空列表
    #data = open('sketch.txt') #打开文件
    with open('sketch.txt') as data:
            for each_line in data:    #按行迭代
                    try:              #和except一起忽略代码的指定错误
                            (role,line_spoken) = each_line.split(':',1)     #使用符号:分割列成为一个元祖赋值给role和line_spoken分别代表人物和说的话
                            line_spoken = line_spoken.strip()               #使用strip()函数去掉空格和回车
    
                            if role == 'Man':                               #判断假如人物是Man,将他说的话用apppend方法追加到man列表
                                    man.append(line_spoken)
                            else:
                                    other.append(line_spoken)               #将其他人说的话追加到other列表
                    except ValueError:
                            pass
            data.close()
    #print man
    #print other
    try:
    #       man_file   = open('man_data.txt','w')
    #       other_file = open('other_data.txt','w')
            with open('man_data.txt','w') as man_file,open('other_data.txt','w') as other_file:
    #       print (man,file=man_file)
    #       print (other,file=other_file)                   #按书里的这语法会报错可能是python3的语法
                    man_file.write(' '.join(man))
                    other_file.write(' '.join(other))               #写文件,需要是字符串格式使用join转换
    except IOError:
            print ('File error')
    #finally:                                                          #不需要执行关闭
    #       man_file.close()    
    #        other_file.close()
    

      删除之前生成的文件man_data.txt和other_data.txt运行新代码,效果和之前的是一样的

     下面向之前学习的print_lol函数增加第四个参数,用来标识把数据写在那个位置.一定要为这个参数

    提供一个缺省值sys.stdout,这样如果调用这个函数没有指定的文件对象则会依然显示在屏幕

    vim 128.py

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    import sys
    man = []
    other = []
    try:
        data = open('sketch.txt')
        for each_line in data:
            try:
                (role,line_spoken) = each_line.split(':',1)
                line_spoken = line_spoken.strip()
                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!')
    
    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("	",end='',file=fn)
                print (each_item,file=fn)
    
    
    try:
        with open('man_data.txt','w') as man_file:
            print_lol(man,fn=man_file)		#python3.5的写文件方法,2.7不适用
        with open('other_data.txt','w') as other_file:
            print_lol(other,fn=other_file)
    except IOError as err:
        print('File error:' + str(err))
    

    PS:这个为后来补充的按照书里python3的语法写的

    执行这个脚本生成的文件内容如下

    "腌制"数据

    Python提供了一个标准库,名为pickle他可以保存和加载几乎任何Python数据对象,包括列表

    使用pickle很简单,只需要导入需要的模块,然后使用dump()保存数据,在以后的某个时间

    使用load()恢复数据。出来数据的唯一要求必须以二进制模式打开文件

    vim sketch-6.py

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    import pickle                                   #导入模块
    with open('mydata.pickle','wb') as mysavedata:  #b参数以二进制方式打开
            pickle.dump([1,2,'there'],mysavedata)   #保存时刻
    with open('mydata.pickle','rb') as myrestoredata:
            a_list = pickle.load(myrestoredata)     #恢复数据赋值给a_list
    print(a_list)
    

      输出

    [root@VPN chapter3]# python sketch-6.py
    [1, 2, 'there']

  • 相关阅读:
    shell 脚本模板
    运动拉伸
    nature作图要求
    R语言画图曼哈顿图来源网络
    选择合适的统计图形和统计方法|图片来自松哥统计
    GO富集图
    batch gene expression plot
    植物生理生化研究进展
    手机图片
    jquery练习之超链接提示效果
  • 原文地址:https://www.cnblogs.com/minseo/p/6750390.html
Copyright © 2011-2022 走看看