美文网首页
python中上下文管理器

python中上下文管理器

作者: 转身丶即天涯 | 来源:发表于2018-09-04 00:21 被阅读8次

什么是上下文管理器?

代码的环境就是上下文,实现了上下文管理器协议的类产生的实例就是上下文管理器对象。
在类中声名enterexit方法的就时实现了上下文管理器协议,也就是说,只要定义了这两个方法,这个类的实例就是上下文管理器对象。

在数据库中的应用

在不适用上下文管理器对象时,我们一般按照连接数据库,sql操作,读取数据,断开连接这样的顺序进行编码,可是连接数据库和断开连接这两部是所有操作都必须要做的事,所以当有大量sql时,按照这样的逻辑些代码会造成大量的冗余代码。
我们先来看一下最原始的写法:

class Database():
    def __init__(self):
        self.connected = False

    def connect(self):
        self.connected = True

    def close(self):
        self.connected = False

    def query(self):
        if self.connected:
            return "query data"
        else:
            raise ValueError("DB not connected.")

def handle_query():
    db = Database()
    db.connect()
    print("handling......", db.query())
    db.close()

上面这段代码中,创建了一个数据库类Database,里面定义了一个connected属性,用来表示是否已经连接上数据库。
connect方法代表连接数据库操作。close方法代表关闭数据库连接。query方法代表查询操作。
这是最容易想到,也是最基础的操作逻辑。

生成器也能解决这个问题

生成器本质上是一个方法,就像在你所写的函数上套了一层接口。看一个简单示例

def dbconn(fn):
    def wrapper(*args, **kwargs):
        db = Database()
        db.connect()
        ret = fn(db, *args, **kwargs)
        db.close()
        return ret
    return wrapper

@dbconn
def handle_query(db=None):
    print("handle---", db.query())

with可以更优雅的解决这个问题

class Database():
    def __init__(self):
        self.connected = False

    def connect(self):
        self.connected = True

    def close(self):
        self.connected = False

    def query(self):
        if self.connected:
            return "query data"
        else:
            raise ValueError("DB not connected.")

    def __enter__(self):
        self.connect()
        return self

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

# 使用with来解决
def handle_query():
    with Database() as db:
        print("handle...", db.query())

# 调用handle_query()
handle_query()

可以明显的看到,Database这个类中加入了enterexit方法。
这样Database()就产生了一个实现了上下文管理器协议的对象,就可以使用with语句了。
with语句会自动处理连接和断开。

with语句怎么就自动处理了呢?

当然还是需要我们使用代码来控制的。首先with Database() as db: 这句代码中的db,就是enter方法的返回值。
而且执行这句话的时候代码会先执行enter方法,这时就做了连接数据库的操作。
然后才是执行了print("handle...", db.query())这句代码,表示处理查询sql。
当print语句(也就是查询语句)执行完了,会回调exit方法,在这里写上关闭数据库连接的代码。
这样我们就不用无限制的写连接和断开的代码了。完美解决。

这个exit方法很安全,因为当with语句中的函数体引发了异常时,也会调用eixt方法,这样就会断开数据库的连接了。

相关文章

  • python中上下文管理器

    什么是上下文管理器? 代码的环境就是上下文,实现了上下文管理器协议的类产生的实例就是上下文管理器对象。在类中声名e...

  • 算法面试 - 问题记录

    python上下文管理器,装饰器? (1)上下文管理器知乎链接:https://zhuanlan.zhihu.co...

  • Python上下文管理器和with块

    python中with语句用起来很方便,那这后边的原理就是python中的上下文管理器。 1.什么是上下文管理器 ...

  • 上下文管理器完成类的功能

    在python中上下文管理器一般是在文件操作时候使用的,打开文件,关闭文件。同时,他还可以将类的功能完成。下面我们看看。

  • python 上下文管理器

    一、什么是上下文管理器? 上下文管理器类型是python的内置类型之一,上下文管理器的定义:允许用户自定义类来定义...

  • Python中上下文管理器及其实现原理

    什么是上下文管理器? 我们常见的上下文管理器with open('test.txt', 'w') as f:。wi...

  • Python上下文管理器

    Context Manager 文档翻译 Python with语句支持上下文管理器定义的运行时上下文概念(run...

  • python上下文管理

    什么是上下文管理 上下文:context的直译, 指的是代码执行过程中的前后状态上下文管理器:python上下文管...

  • python 基础深入

    contextlib 上下文管理器 创建上下文管理实际就是创建一个类,添加enter和exit方法 Python...

  • Tornado源码分析(二)异步上下文管理(StackConte

    异步异常与上下文 在Python黑魔法---上下文管理器最后关于上下文的使用,提到了tornado的处理方式。本篇...

网友评论

      本文标题:python中上下文管理器

      本文链接:https://www.haomeiwen.com/subject/sbfiwftx.html