《Head First Python》第四章--持久存储

  • 读文件
man = []
other = []

try:
    data = open('sketch.txt')
    for each_line in data:
        try:
            (role, line_spoken) = each_line.split(':', 1)
            # 删除line_spoken中不需要的空白符
            line_spoken = line_spoken.strip()
            # 如果时Man说的话,加到man列表中
            if role == 'Man':
                man.append(line_spoken)
            # 如果时Other Man说的话,加到other列表中
            elif role == 'Other Man':
                other.append(line_spoken)
        except ValueError:
            pass
    print('man[] = ', end='')
    print(man)
    print('other[] = ', end='')
    print(other)

    data.close()
except IOError:
    print('the file is missing!')

  • 写文件
man = []
other = []

try:
    data = open('sketch.txt')
    for each_line in data:
        try:
            (role, line_spoken) = each_line.split(':', 1)
            # 删除line_spoken中不需要的空白符
            line_spoken = line_spoken.strip()
            # 如果时Man说的话,加到man列表中
            if role == 'Man':
                man.append(line_spoken)
            # 如果时Other Man说的话,加到other列表中
            elif role == 'Other Man':
                other.append(line_spoken)
        except ValueError:
            pass
    print('man[] = ', end='')
    print(man)
    print('other[] = ', end='')
    print(other)

    data.close()
except IOError:
    print('the file is missing!')

# 使用访问模式w时, Python会打开指定的文件来完成写,
# 如果文件已存在则清空现有内容,
# 如果不存在则先创建文件
out = open('man.out', 'w')
print(man, file=out)

# 关闭文件,相当于刷新(flushing)
out.close()

  • 写覆盖
man = []
other = []

try:
    data = open('sketch.txt')
    for each_line in data:
        try:
            (role, line_spoken) = each_line.split(':', 1)
            # 删除line_spoken中不需要的空白符
            line_spoken = line_spoken.strip()
            # 如果时Man说的话,加到man列表中
            if role == 'Man':
                man.append(line_spoken)
            # 如果时Other Man说的话,加到other列表中
            elif role == 'Other Man':
                other.append(line_spoken)
        except ValueError:
            pass
    print('man[] = ', end='')
    print(man)
    print('other[] = ', end='')
    print(other)

    data.close()
except IOError:
    print('the file is missing!')

# 使用访问模式w时, Python会打开指定的文件来完成写,
# 如果文件已存在则清空现有内容,
# 如果不存在则先创建文件
out = open('man.out', 'w')
print(man, file=out)

# 关闭文件,相当于刷新(flushing)
out.close()

outother = open('man.out', 'w')
print(other, file=outother)
outother.close()

  • 写追加
# !/usr/bin/env python
# -*- coding: utf-8 -*-
man = []
other = []

try:
    data = open('sketch.txt')
    for each_line in data:
        try:
            (role, line_spoken) = each_line.split(':', 1)
            # 删除line_spoken中不需要的空白符
            line_spoken = line_spoken.strip()
            # 如果时Man说的话,加到man列表中
            if role == 'Man':
                man.append(line_spoken)
            # 如果时Other Man说的话,加到other列表中
            elif role == 'Other Man':
                other.append(line_spoken)
        except ValueError:
            pass
    print('man[] = ', end='')
    print(man)
    print('other[] = ', end='')
    print(other)

    data.close()
except IOError:
    print('the file is missing!')

try:
    # 使用访问模式w时, Python会打开指定的文件来完成写,
    # 如果文件已存在则清空现有内容,
    # 如果不存在则先创建文件
    out = open('man.out', 'w')
    print(man, file=out)

    # 关闭文件,相当于刷新(flushing)
    out.close()

    other_data = open('man.out', 'a')
    print(other, file=other_data)
    other_data.close()
except:
    print('File error')




  • 这里其实还存在一个小问题,我在写文件时,捕获了IOError,这会不会对代码造成影响呢?我们现在都知道在进行文件操作时需要捕获IORError,需要关闭文件,但是,如果在print时出现一个IOError,程序会怎么处理?后面的代码还会执行吗?文件还会关闭吗?答案时肯定不会的,所以我们需要新的机制,在捕获异常时,必须有一段代码是一定能够执行的,不被异常捕获而中断。
  • 用finally扩展try
# !/usr/bin/env python
# -*- coding: utf-8 -*-
man = []
other = []

try:
    data = open('sketch.txt')
    for each_line in data:
        try:
            (role, line_spoken) = each_line.split(':', 1)
            # 删除line_spoken中不需要的空白符
            line_spoken = line_spoken.strip()
            # 如果时Man说的话,加到man列表中
            if role == 'Man':
                man.append(line_spoken)
            # 如果时Other Man说的话,加到other列表中
            elif role == 'Other Man':
                other.append(line_spoken)
        except ValueError:
            pass
    print('man[] = ', end='')
    print(man)
    print('other[] = ', end='')
    print(other)

    data.close()
except IOError:
    print('the file is missing!')

try:
    # 使用访问模式w时, Python会打开指定的文件来完成写,
    # 如果文件已存在则清空现有内容,
    # 如果不存在则先创建文件
    out = open('man.out', 'w')
    print(man, file=out)
    other_data = open('man.out', 'a')
    print(other, file=other_data)

except IOError:
    print('File error')
    
finally:
    # 关闭文件,相当于刷新(flushing)
    out.close()
    other_data.close()
  • 在出现异常时,先执行finally代码块,然后才会终止程序,这样文件就不会因为出现异常而无法关闭。finall代码块是一段进入try代码块后一定会执行的部分。
  • 在这里我们直接调用的关闭方法,可是当文件不存在时,是否还能直接调用关闭呢?
  • 当文件不存在时,数据文件对象并未创建,这样就不可能再数据对象上调用close()方法,所以出现一个NameError错误。
  • 这里会再locals()BIF返回的集合中搜索字符串data,如果找到,可以认为文件成功打开
  • 这里只返回了File Error,可是我们却并不清楚是什么导致了这个错误,那么我们是否可以得到具体的错误信息呢?
  • 为异常对象给定一个名,然后作为错误消息的一部分
  • 这里要注意err是一个异常对象,并不能和字符串相连接,故需要强制类型转换str(err)
  • 用with处理文件
  • 由于处理文件时 try/except/finally非常常用,所以Python提供了一个语句来抽象出相关的一些细节。对文件使用with语句时,with可以妥善地关闭一个可能打开的数据文件,而不需要finally代码块
man = []
other = []

try:
    with open('sketch.txt') as data:
        for each_line in data:
            try:
                (role, line_spoken) = each_line.split(':', 1)
                # 删除line_spoken中不需要的空白符
                line_spoken = line_spoken.strip()
                # 如果时Man说的话,加到man列表中
                if role == 'Man':
                    man.append(line_spoken)
                # 如果时Other Man说的话,加到other列表中
                elif role == 'Other Man':
                    other.append(line_spoken)
            except ValueError as verr:
                print('Value Error: ' + str(verr))
                pass
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到屏幕
  • 数据没有格式,完全是列表储方式的输出
  • 怎样格式化内容呢?存储时格式化还是读取时格式化?
  • 读取时再格式化当然是可以的,但这需要大量的额外逻辑,另外,如果是一个协作项目,与你对接的人怎么知道你的文件内容,该怎样格式化呢?所以我们可能需要把数据存储成一种更容易解析的格式
  • 腌制数据
  • Python提供了一个标准库, 名为pickle,它可以保存和加载任何python数据对象,包括列表
  • 一旦把某个数据“腌制”到一个文件,它将会持久存储,可以在以后某个时间都入到另外一个程序。
  • 用dump保存,用load恢复
  • 使用pickle只需导入所需的模块,处理数据的唯一要求是必须以二进制模式打开这些文件
  • dump“腌制”数据
import pickle

man = []
other = []

try:
    with open('sketch.txt') as data:
        for each_line in data:
            try:
                (role, line_spoken) = each_line.split(':', 1)
                # 删除line_spoken中不需要的空白符
                line_spoken = line_spoken.strip()
                # 如果时Man说的话,加到man列表中
                if role == 'Man':
                    man.append(line_spoken)
                # 如果时Other Man说的话,加到other列表中
                elif role == 'Other Man':
                    other.append(line_spoken)
            except ValueError as verr:
                print('Value Error: ' + str(verr))
                pass
except IOError as err:
    print('File Error: ' + str(err))

try:
    with open('man_data.txt', 'wb') as man_file:
        pickle.dump(man, man_file)
    with open('other_data.txt', 'wb') as other_file:
        pickle.dump(other, other_file)
except IOError as err:
    print('File Error: ' + str(err))

  • ????pickle的数据存储的是个什么鬼?不用担心,它本来就是这个样子。python的pickle使用了一种定制的二进制格式。
  • 然后尝试把它读出来

  • 大功告成
  • 使用pickle的通用文件I/O才是上策
  • Python负责你的文件I/O细节,这样你就可以重点关注你的代码实际做什么或者需要做什么
  • BULLET POINTS
  1. “不可变类型” Python中的一些数据类型,一旦赋值,这个值就不能在改变。例如:name = 'zhangsan'   name = 'lisi'这两行代码看似修改name字符串的值,实际上name的值确实改变了,变成了lisi,但是之前的‘zhangsan’的内容并没有改变。name变量只是从指向‘zhangsan’变成了指向‘lisi’,即name='lisi'实际是做了两件事:1.新建了一个‘lisi’的字符串 2.name指向‘lisi’
  2. Python变量只包含数据对象的一个引用,数据对象才真正包含数据。
  3. print(value, sep=' ', end='\n', file=sys.stdout)默认地BIF会显示到屏幕(sys.stdout),这个file参数是第四个位置参数,不过,如果想把数据输出到屏幕以外的地方,也不必为第二个或者第三个位置的参数提供值,因为他们也有缺省值。也就是说Python是根据参数名定位参数,跟位置无关,不像其他语言那样直接传递参数就行,而需要连要传递的参数名一起写全。例如,print('name', end='')以‘’空串结尾,不换行。这里就把end=也写上了。
  4. “腌制”是将数据对象保存到一个持久存储中的过程。
  5. “解除腌制”是从持久存储中恢复一个已保存的数据对象的过程。
  6. strip()方法可以从字符串去除不想要的空白符。
  7. finally组总会执行, 而不论try/except语句中发生什么异常。
  8. locals()BIF返回当前作用域中的变量集合。
  9. in操作符用于检查成员关系。
  10. with语句会自动处理所有一代开文件的关闭操作,即使出现遗产个也不例外。with语句也使用as关键字。
  11. 标准库的pickle允许你容易而高效地将Python数据对象保存到磁盘以及从磁盘恢复。
  12. pickle.dump()将数据保存到磁盘。
  13. pickle.load()从磁盘恢复数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值