zoukankan      html  css  js  c++  java
  • 基础知识回顾——上下文管理器

    上下文管理机制

    很多情况,当我们使用完一个资源后,我们需要手动的关闭掉它,比如操作文件,建立数据库连接等。但是,在使用资源的过程中,如果遇到异常,很可能错误被直接抛出,导致来不及关闭资源。所以在大部分时候,我们使用”try-finally”语句来确保资源会关闭。

    1 try:
    2     f = open('test.txt', 'w+')
    3     print(f.closed)        #判断文件是否关闭
    4     f.write('Hello World!')
    5 finally:
    6     f.close()
    7     print(f.closed)        #判断文件是否关闭

    运行结果:

    False
    True    

    Python语言里提供的with语句功能几乎同”try-finally”一样,代码更简洁。

    1 with open("test.txt", "w") as f:
    2     print(f.closed)
    3     f.write("Hello World!")
    4 print(f.closed)

    运行结果:

    False
    True 

    以上即是上下文管理器的用法,Python要求在with语句进入时自动调用__enter__()方法,其返回值会赋给as关键字后的变量;在with语句块退出后自动调用__exit__()方法。对于文件对象f来说,它定义了__enter__()和__exit__()方法(可以通过dir(f)看到)。在f的__exit__()方法中,有self.close()语句,这样就不用明文写f.close()了。

    自定义上下文管理器

    要自定义类似with语句的类,其内部必须提供两个内置方法__enter__以及__exit__。前者在主体代码执行前执行,后则在主体代码执行后执行。__enter__()返回的一对象作为as所指的变量。

     1 class ContextManagerDemo(object):
     2     def __init__(self,text):
     3         self.text = text
     4 
     5     def __enter__(self):
     6         self.text = "I say: " + self.text
     7         #print self     <__main__.ContextManagerDemo object at 0x023557D0>
     8         return self
     9 
    10     def __exit__(self, exc_type, exc_val, exc_tb):  
    11         self.text = self.text + "!"
    12 #参数exc_type, exc_val, exc_tb分别代表异常类型,异常值,和异常的Traceback。当处理完异常后,可以让”__exit__()”方法返回True,此时该异常就不会再被抛出。正常程序中三个参数都是None
    13 
    14 with ContextManagerDemo('hello') as f:      #上下文管理器会使用__enter__()返回的这一对象作为as所指的变量f,如果没有返回对象,text属性则无法调用
    15     print f.text
    16 
    17 print f.text

    运行结果:

    1 I say: hello
    2 I say: hello!

    上下文管理器应用

    1.管理多个文件

    1 with open('data.txt') as source, open('target.txt', 'w') as target:
    2             target.write(source.read())

    2.管理数据库游标

     1 import pymysql 
     2 
     3 def get_conn(**kwargs): 
     4   return pymysql.connect(host=kwargs.get('host', 'localhost'),
                     port=kwargs.get('port', 8080),
                     user=kwargs.get('user'),
                     passwd=kwargs.get('passwd')) 5 6 def main(): 7   conn = get_conn(user='Admin', passwd='123456') 8   with conn as cur: 9      cur.execute('show databases') 10     print cur.fetchall() 11 12 if __name__ == '__main__': 13   main()
  • 相关阅读:
    .net 命名规范
    解决Swagger刷新后不能保持登录问题
    修改表结构后视图错位问题
    创建.net api文档
    编写.net core tools教程
    VuePress 侧边栏几种配置
    VS 好用快捷键
    Jenkins 修改端口
    获取当前被调用的方法
    遇到异常 add-migration Build failed 解决办法
  • 原文地址:https://www.cnblogs.com/Ryana/p/6249795.html
Copyright © 2011-2022 走看看