python——序列化,反序列化和异常处理

一序列化和反序列化

通过文件操作,我们可以将字符串写入到一个本地文件,但是,如果是一个对象(如列表、字典、元组等),就无法直接写入到文件里,需要对这个对象进行序列化,然后才能写入到文件里
设计一套协议,按照某种规则,把内存中的数据转换为字节序列,保存到文件,这就是序列化,反之,从文件的字节序列恢复到内存中,就是反序列化。
JSON和PICKLE两个模块用来实现数据的序列化和反序列化

二json字符串

json本质就是字符串,区别在于json里要是使用双引号 表示字符串
json用于在不同平台间传递数据

(1)序列化的两个方法:

#1、json.dumps  将数据转换成为字符串,不会把数据保存到文件里
import json
#file.write('张三')#write只能写入字符串或者二进制
names = ['zhangsan', 'lisi', 'jack', 'tony']
x = json.dumps(names)#dumps  是将数据转换成为字符串
#print(x)#["zhangsan", "lisi", "jack", "tony"]

file = open('name.txt', 'w', encoding='utf8')
file.write(x)
file.close()

在这里插入图片描述

#2、json.dump()  可以直接将数据转换成为字符串,且写入到指定文件
names = ['zhangsan', 'lisi', 'jack', 'tony']
file = open('names.txt', 'w', encoding='utf8')

json.dump(names, file)
file.close()

在这里插入图片描述

(2)反序列化的两个方法:

#1、loads  将json字符串加载成为pyth里的数据

import json
x = '{"name":"zhangsan", "age":18}'#符合json规则的字符串
p = json.loads(x)
print(p, type(p))


输出“:
{'name': 'zhangsan', 'age': 18} <class 'dict'>
#2、load   读取一个文件,把文件里json字符串加载成为对象
file1 = open('names.txt', 'r', encoding='utf8')
y = json.load(file1)
print(y)
print(y[0])
file1.close()
输出:
['zhangsan', 'lisi', 'jack', 'tony']
zhangsan

python对象与json字符串的对应关系

pythonjson
dictobjec
list,tuplearray
strstring
int,floatnumber
Truetrue
Falsefalse
Nonenull

三pickle模块

将python里任意的对象转换成为二进制
序列化:dumps(将python中的数据转换成二进制)
dump(将python中的数据转换成二进制,同时保存大指定文件)
反序列化:loads(将二进制加载转换成为python数据)
load(读取文件,并将文件的二进制内容加载成为python数据)

import pickle
names = ['zhangsan', 'lisi', 'jack', 'harry']
b_names = pickle.dumps(names)


file = open('names.txt', 'wb')
file.write(b_names)#写入的是二进制不是纯文本
file.close()

file1 = open('names.txt', 'rb')
x = file1.read()
y = pickle.loads(x)
print(y)
file1.close()

输出:
['zhangsan', 'lisi', 'jack', 'harry']

或:

import pickle
names = ['zhangsan', 'lisi', 'jack', 'harry']

file2 = open('names.txt', 'wb')
pickle.dump(names, file2)
file2.close()

file3 = open('names.txt', 'rb')
y = pickle.load(file3)
print(y)
file3.close()

输出:
['zhangsan', 'lisi', 'jack', 'harry']
class Dog(object):
    def __init__(self, name, color):
        self.name = name
        self.color = color
    def eat(self):
        print(self.name + '正在吃东西')

d = Dog('大黄', '白色')
#保存到文件里
pickle.dump(d, open('dog.txt', 'wb'))
#从文件里加载出来
dd = pickle.load(open('dog.txt', 'rb'))
dd.eat()
print(dd.name, dd.color)
输出:
大黄正在吃东西
大黄 白色

四json与pickle的区别

pickle用来将数据原封不动的转换成为二进制,但是二进制只能在python里识别
json只能保存一部分信息,作用是用来在不同的平台里传递数据。json里存储的数据都是基本的数据类型

在这里插入图片描述

五异常处理

在程序运行过程中,由于编码不规范等造成程序无法正常运行,此时程序会报错
try except else语句

def div(a, b):
    return a / b
try:
    x = div(5, 0)
    print('hhhh')
except Exception as e:  #如果程序出错会立刻跳到except语句
    print('程序出错')
else:#当程序运行没有出错会执行else语句代码
    print('计算结果是:', x)

输出:
程序出错

try … except … else语句用来处理程序运行过程中的异常

try:
    print(1 / 0)
    file = open('ddd.txt')
    print(file.read())
    file.close()
except Exception as e:#给异常取了个变量名#Exception 错误类型
    print(e)
#except (FileNotFoundError, ZeroDivisionError) as e:
#    print('出错了')
输出:
division by zero

六 finally关键字的使用

1、finally:最终都会执行的代码

file = open('../红楼梦.txt', 'rb')

try:
    while True:
        count = file.read(1)
        if not count:
            break
        print(count)

finally:#最终都会执行的代码
    print('文件关闭')
    file.close()

输出:
......(省略前面输出的大量数据)
b'\xcd'
b'\xbc'
b'\xca'
b'\xe9'
b'\xa3'
b'\xa1'
文件关闭

2、如果函数里有finall,finall返回的值会覆盖之前的返回值

def test(a, b):
    x = a + b
    return x

def demo(a, b):
    try:
        x = a / b
    except Exception as e:
        print( '除数不能为零')
    else:
        return x

    finally:
        return 'good'#如果函数里有finall,finall返回的值会覆盖之前的返回值 

print(demo(1, 2))
print(demo(1, 0))
输出
good
除数不能为零
good

七 with关键字

1、with上下文管理器,很多需要手动关闭的连接,都可以使用with关键字的自动关闭连接

try:
    file = open('name.txt', 'r')
except FileNotFoundError:
    print('文件不存在')
else:
    try:
        file.read()
    finally:
        file.close()

改进:

try:
    with open('name.txt', 'r', encoding='utf8') as file:
        file.read()#不需要再手动关闭文件
        #file.close()  #with关键字会帮助我们关闭文件
except FileNotFoundError:
    print('文件未找到')

2、with关键字后面的对象,需要实现__enter__和 __exit __魔法方法

3、上下文管理器

在进入到上下文时,会自动调用__enter__()方法,程序正常执行完成,或出现异常中断的时候,都会调用__exit __()方法
with语句后面的对象,需要重写__enter__和 __exit __方法,当进入到with代码块时,会自动调用__enter__方法里的代码,当with代码块执行完成以后,会自动调用__exit __方法里的代码

class Demo(object):
    def __enter__(self):
        print('__enter__被执行')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('__exit__被调用')

def creat_obj():
    x = Demo()
    return x



with creat_obj() as d:#as + 变量名
    print(d)#变量d不是creat_obj()的返回结果,它是创建的对象x调用__enter__()之后返回的结果
输出:
__enter__被执行
<__main__.Demo object at 0x000001F768A564F0>
__exit__被调用

八 自定义异常

系统内置的异常:
ZeroDivisionError(除以0)
FileNotFoundError(文件不存在异常)
FileExistsError (多次创建同名文件异常)
ValueError( 类型转换异常)
KeyError(键错误异常)
SyntaxError(语法错误:英文字符用中文)
IndexError(角标错误)

class LenthError(Exception):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return '长度必须要在{}至{}之间'.format(self.x, self.y)

password = input('请输入密码:')
m = 6
n = 12
if m<= len(password) <=n:
    print('密码正确')

else:
    #使用raise 关键字可以抛出一个异常
    raise LenthError(m, n)

输出:
在这里插入图片描述

九高级装饰器

def can_play(fn):
    print('外部函数被调用')

    def inner(name, game, **kwargs):
        clock = kwargs.get('clock', 21)
        if clock >= 21:
            print('太晚了不能玩游戏了')
        else:
             fn(name, game)

    return inner



# def can_play():
#     pass

@can_play
def play_game(name, game):
    print(name + '正在玩' + game)
   
 play_game('张三', '王者荣耀', clock = 22)

运行过程:先调用can_play函数,再将被装饰的play_game作为参数传入fn执行inner再返回inner

输出:
外部函数被调用
太晚了不能玩游戏了

改进代码:

def can_play(clock):
    print('最外层函数被调用,clock={}'.format(clock))
    def handle_action(fn):
        def do_action(name, game):
            if clock < 21:
                fn(name, game)
            else:
                print('太晚了,不能玩儿游戏啦')
        return do_action

    return handle_action



@can_play(22)    #装饰器函数带参数
def play_game(name, game):
    print(name + '正在玩儿' + game)



play_game('张三', '王者荣耀')

代码图示:

输出:
最外层函数被调用,clock=22
太晚了,不能玩儿游戏啦

十 装饰器高级使用

user_permission = 11

#权限因子
#用户权限  &  权限因子  !=0  说明有权限可以执行
DEL_PERMISSION = 8     #0b1000
READ_PERMISSION = 4    #0b0100
WRITE_PERMISSION = 2   #0b0010
EXE_PERMISSION = 1     #0b0001
def check_permission(x, y):

    def handle_action(fn):
        def do_action():
            if x & y != 0:
                fn()
            else:
                print('对不起,您没有相应的权限!')

        return do_action
    return handle_action


@check_permission(user_permission, READ_PERMISSION)
def read():
    print('我正在读取内容')


@check_permission(user_permission, WRITE_PERMISSION)
def write():
    print('我正在写入内容')


@check_permission(user_permission, EXE_PERMISSION)
def execute():
    print('我正在执行任务')


@check_permission(user_permission, DEL_PERMISSION)
def delete():
    print('我正在删除')

read()
write()
execute()
delete()
输出:
对不起,您没有相应的权限!
我正在写入内容
我正在执行任务
我正在删除
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值