python 上下文管理

如何写上下文管理器?

要自己实现这样一个上下文管理,要先知道上下文管理协议。
简单点说,就是在一个类里,实现了__enter__和__exit__的方法,这个类的实例就是一个上下文管理器。
在 写__exit__ 函数时,需要注意的事,它必须要有这三个参数:
exc_type:异常类型
exc_val:异常值
exc_tb:异常的错误栈信息
当主逻辑代码没有报异常时,这三个参数将都为None

为什么要使用上下文管理器?

这和 Python 崇尚的优雅风格有关。
可以以一种更加优雅的方式,操作(创建/获取/释放)资源,如文件操作、数据库连接;
可以以一种更加优雅的方式,处理异常;
第一种,我们上面已经以资源的连接为例讲过了。
第二种,会被大多数人所忽略。这里会重点讲一下。
大家都知道,处理异常,通常都是使用 try…execept… 来捕获处理的。这样做一个不好的地方是,在代码的主逻辑里,会有大量的异常处理代理,这会很大的影响我们的可读性。
好一点的做法呢,可以使用 with 将异常的处理隐藏起来。

基于python 的contextlib实现上下文管理

@contextlib.contextmanager装饰器使用

# -*- coding: UTF-8 -*-
import contextlib
import random
import threading
import time
import pymysql

@contextlib.contextmanager
def FileHander(filename):
    handler = open(filename, 'r')
    try:
        yield handler
    except Exception as err:
        print(err)
    finally:
        handler.close()
        return

 with FileHander(r"E:\Blob\requirments.txt") as f:
     for i in f.readlines():
         print(i)

HOST = "xxx.xxx.x.x"
PORT = 3306
USER = "xxx"
PASSWORD = "xxx"
DATABASE = "xxx"

@contextlib.contextmanager
def DBConnect(**kwargs):
    host = kwargs.get("host")
    user = kwargs.get("user")
    pwd = kwargs.get("pwd")
    port = kwargs.get("port")
    database = kwargs.get("database")
    conn = pymysql.connect(host=host, port=port, user=user, password=pwd, database=database, charset="utf8")
    cursor = conn.cursor()
    try:
        yield (conn,conn.cursor)
    except Exception as err:
        print(err)
    finally:
        cursor.close()
        conn.close()

kw = dict(host=HOST, port=PORT, user=USER, pwd=PASSWORD, database=DATABASE)

def connectDB(i):
    with DBConnect(**kw) as c:
        conn, cursor = c[0], c[1]
        print(f"id:{i};{id(conn)}")
        print(f"id:{i};{id(cursor)}")

import threading
ts = [threading.Thread(target=connectDB,args=(i,)) for i in range(3)]
for i in ts:
    i.start()
for i in ts:
    i.join()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值