HeadFirstPython---------(二)第四章,持久存储,数据保存到文件

1、将基于内存的数据存储到磁盘上,这正是持久存储的含义。

sketch.txt文件内容如下:

Man: Is this the right room for an argument?

Other Man: I've told you once.

Man: No you haven't!

Other Man: Yes I have.

Man: When?

Other Man: Just now.

Man: No you didn't!

Other Man: Yes I did!

Man: You didn't!

Other Man: I'm telling you, I did!

Man: You did not!

Other Man: Oh I'm sorry, is this a five minute argument, or the full half hour?

Man: Ah! (taking out his wallet and paying) Just the five minutes.

Other Man: Just the five minutes. Thank you.

Other Man: Anyway, I did.

Man: You most certainly did not!

Other Man: Now let's get one thing quite clear: I most definitely told you!

Man: Oh no you didn't!

Other Man: Oh yes I did!

Man: Oh no you didn't!

Other Man: Oh yes I did!

Man: Oh look, this isn't an argument!

(pause)

Other Man: Yes it is!

Man: No it isn't!

(pause)

Man: It's just contradiction!

Other Man: No it isn't!

Man: It IS!

Other Man: It is NOT!

Man: You just contradicted me!

Other Man: No I didn't!

Man: You DID!

Other Man: No no no!

Man: You did just then!

Other Man: Nonsense!

Man: (exasperated) Oh, this is futile!!

(pause)

Other Man: No it isn't!

Man: Yes it is!



代码如下:

import os
os.chdir("D:/pythontest/HeadFirstPython/chapter3/");
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();#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!');
print(man);
print(other);

实验结果为:


改进:避免了数据的破坏,无论出现还是不出现异常,文件都会正常的关闭。

import os
os.chdir("D:/pythontest/HeadFirstPython/chapter3/");
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();#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!');
try:
    man_data=open("man_data.txt",'w');
    other_data=open("other_data.txt",'w');
    
    print(man,file=man_data);
    print(other,file=other_data);
    
except IOError:
    print('File error');
finally:
    man_data.close();
    other_data.close();

2、为异常对象给定一个名,异常对象与字符串类型不兼容。

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

实验结果为:


修改,异常对象为字符串类型

try:
data=open('missing.txt');
print(data.readline(),end='');
except IOError as err:
print('File error'+str(err));#使str()BIF要求异常对象表现为一个字符串。
finally:
if 'data'in locals():
data.close();
 

输出结果为:


现在你会得到一个特定的错误消息,指出到底哪里出了问题。

3、使用with就不在需要finally组了;使用with时,不再需要操心关闭打开的文件,下面的代码等同于上面finally部分(关闭文件的代码)。

代码如下:

try:
    with open('its.txt','w') as data:
        print("it's...",file=data);
except IOError as err:
    print('File error:'+str(err));


 

4、读文件和写文件,用with

with介绍:with EXPRESSION [ as VARIABLE] WITH-BLOCK

这个语法是用来代替传统的try...finally语法的。 紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的

代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。

import os
os.chdir("D:/pythontest/HeadFirstPython/chapter3/");
man=[];
other=[];
try:
    with open('sketch.txt','r') as data:
        for each_line in data:
            if not each_line.find(":")==-1:
                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 as err:
                    print("Context of file is:"+str(err));
            else:
                continue;
except IOError as err:
    print("File error"+str(err));
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()将man列表写入haha.txt文件时转换成了一个字符串来存储的)

 

haha.txt中的数据如图:


发现按行读haha.txt中的数据的时候,整个就算是一行。可读性差....................


5、改善,易读的格式呈现出来man_data.txt中的内容:
nester.py中代码如下,

import sys
#level代表列表刚开始,缩进几个tab位,然后每层嵌套在前面缩进的基础上加1。向函数参数提供一个缺省值。
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);

memory.py中的代码如下:

import os
import nester
os.chdir("D:/pythontest/HeadFirstPython/chapter3/");
man=[];
other=[];
try:
    with open('sketch.txt','r') as data:
        for each_line in data:
            if not each_line.find(":")==-1:
                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 as err:
                    print("Context of file is:"+str(err));
            else:
                continue;
except IOError as err:
    print("File error"+str(err));
try:
    with open('man_data.txt','w') as man_file:
        #print(man,file=man_file);
        nester.print_lol(man,fn=man_file);
    with open('other_data.txt','w') as other_file:
        nester.print_lol(other,fn=other_file);
        #print(other,file=other_file);
except IOError as err:
    print("File error:"+str(err));

运行结果为:


是不是变得友好了昂.........................................大笑

6、Python提供了一个标准库,名为pickle,它可以保存和加载几乎任何Python数据对象,包括列表。一旦把数据“腌制”到一个文件,它将会持久存储,可以在以后某个日期/时间读入另外一个程序。

首先,先把数据腌制掉:

import os
import pickle
os.chdir("D:/pythontest/HeadFirstPython/chapter3/");
man=[];
other=[];
try:
    with open('sketch.txt','r') as data:
        for each_line in data:
            if not each_line.find(":")==-1:
                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 as err:
                    print("Context of file is:"+str(err));
            else:
                continue;
except IOError as err:
    print("File error"+str(err));
try:
    with open('man_data.txt','wb') as man_file, open('other_data.txt','wb') as other_file:
        #print(man,file=man_file);
        '''要保存数据使用dump(),处理腌制数据时的唯一要求是,必须以二进制访问模式打开这些文件
        以后某个时间使用load()恢复数据。恢复后,就可以像任何其他数据对象一样处理了。'''
        pickle.dump(man,man_file);
    
        pickle.dump(other,other_file);
        #print(other,file=other_file);
except IOError as err:
    print("File error:"+str(err));
except pickle.PickleError as perr:#腌制或者解除数据腌制时如果出了问题,pickle模块会产生一个PickleError类型的异常。
    print('Pickling error:'+str(perr));
    
结果为:


解腌制,并像任何数据对象一样进行处理:


总结:腌制,即将数据对象保存到一个持久存储中的过程。pickle.dump()函数将数据保存到磁盘。

解除腌制:从持久存储中恢复一个已保存的数据对象的过程。pickle.load()函数从磁盘恢复数据。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值