上下文管理器之《实现文件关闭、提取异常类型、异常值、异常追踪溯源信息》

2022-04-27 19:24:20 浏览数 (1)

1.把文件打开方式改成utf8

在Windows中默认文件打开方式是gbk,把文件打开方式改成utf8:

代码语言:javascript复制


class  MyOpen(object):
        # 文件操作的上下文管理器类
    def __init__(self,file_name,open_method,encoding='utf8'):
        self.file_name=file_name#做个初始化
        self.open_method=open_method
        self.encoding=encoding

    def __enter__(self):
        self.f=open(self.file_name,self.open_method,encoding=self.encoding) #普通打开文件的方式
        return self.f#如果不写self,要关闭文件,下面exit方法够不到

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

with MyOpen('test.txt','r') as f:
    print(f)

运行结果

这个f是文件操作的句柄,也是文件操作的io对象,打开的文件名字是这个test.txt,方式是以r的方式打开。

代码语言:javascript复制


class  MyOpen(object):
        # 文件操作的上下文管理器类
    def __init__(self,file_name,open_method,encoding='utf8'):
        self.file_name=file_name#做个初始化
        self.open_method=open_method
        self.encoding=encoding

    def __enter__(self):
        self.f=open(self.file_name,self.open_method,encoding=self.encoding) #普通打开文件的方式
        return self.f#如果不写self,要关闭文件,下面exit方法够不到

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

with MyOpen('test.txt','r') as f:
    print(f)

with MyOpen('test1.txt','w') as f:
    print(f)

运行结果

2.实现关闭文件

上下文管理器的操作,我们实现了,但是文件关闭没实现。当with下面代码运行结束的时候,会触发__exit__方法。

__exit__方法里面实现对文件进行关闭。

代码语言:javascript复制
 def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()

那么这就是一个文件操作的上下文管理器的一个实现:

接下来,来这里面读点内容:

代码语言:javascript复制
with MyOpen('test.txt','r') as f:
    content=f.read()
    print(content)

代码:

代码语言:javascript复制


class  MyOpen(object):
        # 文件操作的上下文管理器类
    def __init__(self,file_name,open_method,encoding='utf8'):
        self.file_name=file_name#做个初始化
        self.open_method=open_method
        self.encoding=encoding

    def __enter__(self):
        self.f=open(self.file_name,self.open_method,encoding=self.encoding) #普通打开文件的方式
        return self.f#如果不写self,要关闭文件,下面exit方法够不到

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()

with MyOpen('test.txt','r') as f:
    content=f.read()
    print(content)

运行结果

这个上下文管理器已经实现了。那么这个上下文管理器with后面处理的是一个上下文管理器对象:

这里是通过MyOpen这个类创建一个对象,然后然后返回到这里。这个时候通过with去处理这个对象的时候,会自动调用这个对象的__enter__魔术方法。并且将这个魔术方法返回出来内容as一下f。

那么f接收到的就是下面这个方法返回的内容:

代码语言:javascript复制
    def __enter__(self):
        self.f=open(self.file_name,self.open_method,encoding=self.encoding) #普通打开文件的方式
        return self.f#如果不写self,要关闭文件,下面exit方法够不到

那么当with下面的代码执行结束之后,那么又会触发这个对象的__exit__方法。那么在这个方法里面你可以做一些你想做的事情。

通过上下文管理器不光可以操作文件,比如定义一个连接mysql的类,使用with去处理连接mysql上下文管理器的时候会自动创建一个对象建立连接。

把建立好的连接返回出来,然后你在里面进行一个操作。完了之后代码运行结束,自动断开连接。

3.提取异常类型、异常值、异常追踪溯源信息

exc_type:异常类型。

exc_val:异常值。

exc_tb:异常追踪溯源。

1)上下文退出时有异常
代码语言:javascript复制


class  MyOpen(object):
        # 文件操作的上下文管理器类
    def __init__(self,file_name,open_method,encoding='utf8'):
        self.file_name=file_name#做个初始化
        self.open_method=open_method
        self.encoding=encoding

    def __enter__(self):
        self.f=open(self.file_name,self.open_method,encoding=self.encoding) #普通打开文件的方式
        return self.f#如果不写self,要关闭文件,下面exit方法够不到

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        self.f.close()

with MyOpen('test.txt','r') as f:
    content=f.read()
    print(name)
    print(content)

运行结果

name这个变量没有被定义,是个异常信息。运行结果中还有个对象:<traceback object at 0x7f7e70035288>,就是这个异常追踪信息放在这个对象里面。

代码语言:javascript复制
        print(exc_type)
        print(exc_val)
        print(exc_tb)

在这里可以输出日志的相关信息,代码该报错还是会报错的,只是它帮你把异常类型、异常值、异常追踪溯源信息给提取出来。

2)上下文退出时没有异常

如果该上下文退出时没有异常,三个参数都将为None。

运行结果

除标明“图片来自网络”的图片,其它文章中的图片皆为本人所画,计算机知识都一样,如有雷同,纯属巧合。

0 人点赞