美文网首页
python中的with语句

python中的with语句

作者: 转身丶即天涯 | 来源:发表于2018-09-03 15:44 被阅读17次

with语句的作用

先说说为什么会出现with,本来可以用try except finally来解决的问题,为什么要用with语句呢?
因为两个原因,其一,python是一门简短精悍的语言,提倡简洁的编码风格,也可以理解为pythonic。其二,with使用了上下文管理器,可以自动获取上下文相关内容,让开发者更专注于业务。

上下文管理器

前面提到了一个一个概念,上下文管理器,它是python中的一种协议,实现了这种协议的类的实例,都是上下文管理器对象。
那么怎么才能实现协议呢?
python中很简单,只需要在类定义的时候,实现两个方法即可。
一个是enter,另一个是exit
下面我们来看一个示例:

class A():
    def __init__(self, val_a):
        self.a = val_a

    def __enter__(self):
        print("class A‘s __enter__ function.’")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("class A's __exit__ function.")

这样,就创建好了一个实现了上下文管理器协议的对象。你可以应用到任何类中。

Python中还有其他的高级特性也能创建上下文管理器,比如使用装饰器@contextmanager。
请看示例:

from contextlib import contextmanager

@contextmanager
def demo_func():
    print("enter")
    yield "demo_func"
    print("exit")

with demo_func() as value:
    print(value)

上面的代码使用了@contextmanager装饰器,contextmanager装饰被定义在contextlib模块中,所以需要先导入contextlib模块。
使用了@contextmanager装饰器修饰的方法都会变成上下文管理器对象。

上下文管理器先说这些,今天的重点是with语句。

with语句的语法

with expression as targer:
code body

expression是一个表达式,可以是一个函数,也可以是一个对象,但是如果是函数,函数必须返回一个实现了上下文管理器协议的对象,如果是一个对象,这个对象必须是上下文管理器对象。
target,是enter方法的返回值。
好了,目前知道这些就够了。

创建的with用法有哪些呢?

1. 操作文件
import os

with open('/usr/file.txt') as f:
    for line in f:
        print(line)

当操作文件时,with获取了应用上下文,在结束时会自动执行close函数来关闭文件。

2. 操作数据库

我们以Mysql为例,提示:这段代码使用pymysql模块,所以需要先安装,pip install pymysql即可。
如果总是没有反馈结果,可以翻墙,然后再次执行pip install pymysql命令就行了。

from pymysql import connect

class OpenDB():
    def __init__(self, username, password, database):
        self.conn = connect(host="localhost", port=3306, user=username, password=password, database=database, charset='utf-8')
        self.cs = self.conn.cursor()

    def __enter__(self):
        return self.cs    # 返回游标

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.conn.commit()      # 提交sql操作
        self.cs.close()             # 关闭游标
        self.conn.close()         # 关闭数据库连接

with OpenDB('root', '123456', 'test_database') as d:
    sql = "select * from test_database"
    d.execute(sql)
    content = d.fetchall()

for temp in content:
    print(temp)

首先导入pymysql模块中的connect对象,用来初始化数据库的连接。
然后程序创建了一个实现了上下文管理器协议的对象OpenDB,它有两个属性,一个保存了数据库的连接,另一个报错了数据库的游标,因为要通过游标来执行sql语句。

也许你会问,这个d是什么?
d是enter方法的返回值,嗯,很明显,这里的d是指向数据库游标的,所以才有了d.execute(sql)这一句执行sql的代码。
d.fetchall()用来匹配所有的查询结果。
最后用一个for in来遍历查询结果。

with还有很多场景都能用到

比如操作锁的时候,多线程中也会用到,暂时我还没有用过这些场景,未完待续吧。

相关文章

网友评论

      本文标题:python中的with语句

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