Python Day 51 浅淡python中with的用法,上下文管理器

  #案例一安全

class Foo(object):

    def __init__(self):
        print('实例化一个对象')

    def __enter__(self):
        print('进入')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('退出')

obj = Foo()

with obj:
    print('正在执行')


#上面代码执行结果为:
实例化一个对象
进入
正在执行
退出

#结论
咱们知道,实例化Foo,获得obj对象,会执行Foo的__init__方法,也就是打印了第一句;
按照,程序从上至下执行,应该会打印“正在执行”才对,为何会在它以前先打印了进入,在它以后打印了退出呢?
 
由于咱们在定义Foo时,定义了__enter__和__exit__方法,那么咱们实例化的对象obj就是一个上下文管理器,
即含有__enter__和__exit__方法的对象就是上下文管理器。

with 上下文管理器:
     语句体

当with遇到上下文管理器,就会在执行语句体以前,先执行上下文管理器的__enter__方法,而后再执行语句体,执行完语句体后,最后执行__exit__方法
 
这也就是为何会出现文章开头的状况的缘由。

  ##案例二编码

class Foo(object):

    def __init__(self):
        print('实例化一个对象')

    def __enter__(self):
        print('进入')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('退出')
     # return True

obj = Foo()

with obj:
    raise ImportError
    print('正在执行')

  #结果以下spa

  #把上面代码中咱们注释掉的那一行代码取消注释,结果以下code

  咱们会发现,虽然咱们故意在语句体中抛出一个错误,按照正常状况,执行到报错地方就不会执行了,而__exit__是在语句体执行完以后执行的,但仍是执行了__exit__方法;当咱们在__exit__中给一个返回值为Ture时,就会忽略错误。对象

  #结论blog

#结论
全部咱们能够发现
with语句相似
  try :
  except:
  finally:
的功能:可是with语句更简洁。并且更安全。代码量更少。
   出现异常时,若是 __exit__ 返回 False(默认不写返回值时,即为False),则会从新抛出异常,让with 以外的语句逻辑来处理异常,这也是通用作法;若是返回 True,则忽略异常,再也不对异常进行处理

  ##案例三ci

class Foo(object):

    def __init__(self):
        print('实例化一个对象')

    def __enter__(self):
        print('进入')
        # return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('退出')


with Foo() as obj:
    print(obj,type(obj))
    print('正在执行')

  #结果get

  #把上面代码中咱们注释掉的那一行代码取消注释,结果以下it

  #结论io

调用上下文管理器的 __enter__ 方法时;若是使用了 as 子句,则将 __enter__() 方法的返回值赋值给 as 子句中的目标

with 上下文管理器  as  target:
    代码语句体

with后面必须跟一个上下文管理器,若是使用了as,则是把上下文管理器的 __enter__() 方法的返回值赋值给 target,target 能够是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)

  ##案例四

咱们常常会看到这样的代码:
with open("/tmp/foo.txt") as file:
    data = file.read()

  #结论

这里使用了 with 语句,无论在处理文件过程当中是否发生异常,都能保证 with 语句执行完毕后已经关闭了打开的文件句柄。若是使用传统的 try/finally 范式,则要使用相似以下代码:
somefile = open(r'somefileName')
try:
    for line in somefile:
        print line
        # ...more code
finally:
    somefile.close()

比较起来,使用 with 语句能够减小编码量。已经加入对上下文管理协议支持的还有模块 threading、decimal 等。

  #补充

with只能配合上下文管理器使用,常见的上下文管理器有:
file
decimal.Context
thread.LockType
threading.Lock
threading.RLock
threading.Condition
threading.Semaphore
threading.BoundedSemaphore
相关文章
相关标签/搜索