上下文管理器

上下文管理器

上下文管理器执行了__enter__()__exit__()方法

复制代码
read_file = open("1.txt")
write_file = open("2.txt",w)

try:
    r = read_file.readlines()
    for line in r:
        write_file.write(line)
finally:
    read_file.close()
    write_file.close()
复制代码

可以用“上下文管理器”写的更好。所以,用with语句改写之后,就是很优雅的了。

with open('1.txt") as read_file, open("2.txt",w) as write_file:

    for line in read_file.readlines():
            write_flie.write(line)

contextlib模块

Python中的这个模块使上下文管理中非常好用的东东,这也是标准库中的一员,不需要另外安装了

contextlib.closing()

有一种或许常用到的情景,就是连接数据库,并返回一个数据库对象,在使用完之后关闭数据库连接,其形状如下:

with contextlib.closing(CreateDB()) as db:
    db.query()

以上不是可运行的代码,只是一个架势,读者如果在编码中使用,需要根据实际情况改写。

当数据库语句db.query()结束之后,数据库连接自动关闭。

contextlib.nested()

nested的汉语意思是“嵌套的,内装的”,从字面上读者也可能理解了,这个方法跟嵌套有关。前面有一个示例,是从一个文件读取,然后写入到另外一个文件。我不知道读者是否想过可以这么写:

with open("23501.txt") as read_file:
    with open("23503.txt", "w") as write_file:
        for line in read_file.readlines():
            write_file.write(line)

此种写法不是不行,但是不提倡,因为它太不Pythoner了。其实这里就涉及到了嵌套,因此可以使用contextlib.nested重。

with contextlib.nested(open("23501.txt", "r"), open("23503.txt", "w")) as (read_file, write_file):
    for line in read_file.readlines():
        write_file.write(line)

这是一种不错的写法,当然,在本节最前面所用到的写法,也是可以的,只要不用刚才那种嵌套。

contextlib.contextmanager

contextlib.contextmanager是一个装饰器,它作用于生成器函数(也就是带有yield的函数),一单生成器函数被装饰以后,就返回一个上下文管理器,即contextlib.contextmanager因为装饰了一个生成器函数而产生了__enter__()__exit__()方法

特别要提醒,被装饰的生成器函数只能产生一个值,否则就会抛出RuntimeError异常

posted @ 2017-07-31 13:06  天涯海角路  阅读(155)  评论(0)    收藏  举报