1.把文件打开方式改成utf8
在Windows中默认文件打开方式是gbk,把文件打开方式改成utf8:
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)
![0115294c9b9f3ee5b27605ed8c14717c.png](https://i-blog.csdnimg.cn/blog_migrate/0c275c6ff90e4d4c61d9896fa66eb90f.png)
这个f是文件操作的句柄,也是文件操作的io对象,打开的文件名字是这个test.txt,方式是以r的方式打开。
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)
![e47d92bbce24d3a21717871104f4dc85.png](https://i-blog.csdnimg.cn/blog_migrate/04a43d457071472e63ba50eba51dd48b.png)
2.实现关闭文件
上下文管理器的操作,我们实现了,但是文件关闭没实现。当with下面代码运行结束的时候,会触发__exit__
方法。
在__exit__
方法里面实现对文件进行关闭。
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
那么这就是一个文件操作的上下文管理器的一个实现:
![ff89b943a30e19047e88da3980868c57.png](https://i-blog.csdnimg.cn/blog_migrate/d37883d4f3446128892fbddb3b519ac5.png)
接下来,来这里面读点内容:
with MyOpen('test.txt','r') as f:
content=f.read()
print(content)
代码:
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)
![d3860cd43f0bd531edb02047e73b77f6.png](https://i-blog.csdnimg.cn/blog_migrate/d626d06deaf74e3c54ff45ab8e766ae6.png)
这个上下文管理器已经实现了。那么这个上下文管理器with后面处理的是一个上下文管理器对象:
![efcdad7eaa874857f95e9a6f53c43fd8.png](https://i-blog.csdnimg.cn/blog_migrate/7bf876c285b1d244e03b0bfdcab043c9.png)
这里是通过MyOpen这个类创建一个对象,然后然后返回到这里。这个时候通过with去处理这个对象的时候,会自动调用这个对象的__enter__
魔术方法。并且将这个魔术方法返回出来内容as一下f。
那么f接收到的就是下面这个方法返回的内容:
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)上下文退出时有异常
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)
![1c8f7417e23363393ce27bed85d3a6d4.png](https://i-blog.csdnimg.cn/blog_migrate/fe934a69674a741059601626a812e22e.png)
name这个变量没有被定义,是个异常信息。运行结果中还有个对象:<traceback object at 0x7f7e70035288>
,就是这个异常追踪信息放在这个对象里面。
print(exc_type)
print(exc_val)
print(exc_tb)
在这里可以输出日志的相关信息,代码该报错还是会报错的,只是它帮你把异常类型、异常值、异常追踪溯源信息给提取出来。
2)上下文退出时没有异常
如果该上下文退出时没有异常,三个参数都将为None。
![1f636911b4a23119fcddb32b2fe1b75f.png](https://i-blog.csdnimg.cn/blog_migrate/30ef603c20e2b8a3a234913530ded065.png)
除标明“图片来自网络”的图片,其它文章中的图片皆为本人所画,计算机知识都一样,如有雷同,纯属巧合。
公众号 清菡软件测试 首发,更多原创文章:清菡软件测试 164+ 原创文章,欢迎关注、交流,禁止第三方擅自转载。如有转载,请标明出处。