python--上下文管理器

在python中我们打开文件有两种方式,一种是使用open直接打开,还有一种通过with来打开文件

今天自我总结下with打开文件的原理

首先我们明白通过with打开文件后是不需要我们手动去关闭的,但是为什么不需要手动关闭呢?

原因大概是因为在代码底层里面实现了自动关闭的吧

接下来我们分析下原理,首先看以下代码

class B:
    def __enter__(self):
        print("正在执行enter方法")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("正在执行exit方法")


with B() as f:
    print(f)

那么我们直接运行此脚本看看结果:

正在执行enter方法
None
正在执行exit方法

忽略中间那个None(因为没有return),我们看到直接使用with B() ...的话打印的结果是先执行__enter__方法,然后执行__exit__方法

看到这里了你是不是有什么想法?

 

1、可以将打开文件以及操作放在__enter__中

2、将关闭文件的操作放在__exit__中

 

那么我们来实现下

1、将文件打开的操作放在__enter__中,发现需要文件名,这可咋整?

发现在with B()中其实也是要传递文件名以及打开方式等等参数,那么就明白了,参数可以通过__init__方法来传递

class B:
    def __init__(self, file_name, mode, encoding="utf-8"):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def __enter__(self):
        print("正在执行enter方法")
        f = open(self.file_name, self.mode, encoding=self.encoding)
        return f

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("正在执行exit方法")

以上在__enter__中已经实现了打开文件的操作并返回

2、接下来就是在__exit__中实现关闭文件的操作了

  

 1 class B:
 2     def __init__(self, file_name, mode, encoding="utf-8"):
 3         self.file_name = file_name
 4         self.mode = mode
 5         self.encoding = encoding
 6 
 7     def __enter__(self):
 8         print("正在执行enter方法")
 9         self.f = open(self.file_name, self.mode, encoding=self.encoding)
10         return self.f
11 
12     def __exit__(self, exc_type, exc_val, exc_tb):
13         print("正在执行exit方法")
14         self.f.close()

 

 

那么我们接下来执行下,目前我这个文件已经存在内容了,我们来读取下

with B("b.txt", "r") as f:
    print(f.read())

执行结果:

1 正在执行enter方法
2 ceshi cehsi
3 正在执行exit方法

结果很完美,打开文件,然后读取,最后关闭

至于python上下文管理器可以干嘛?我觉得做自动化测试里面也可以用到,比如自动化中连接数据库的代码

    class DB:
        """
        上下文管理器实现连接MySQL
        """
        def __init__(self, host,port,user,password,charset,database):
            self.conn = pymysql.connect(host=host,
                                        port=port,
                                        user=user,
                                        password=password,
                                        charset=charset,
                                        database=database)
            self.cursor = self.conn.cursor()

        def __enter__(self):
            return self.cursor

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

 

上面也就是本人对python中上下文管理器的一点认识,请大家批评指正!

posted @ 2020-04-04 17:28  大渝  阅读(191)  评论(0编辑  收藏  举报