原文地址:Python中的With…as语句(简书-惑也)

一、语法

  1. with context as var:
  2. with_suite
  • with语句:可以代替try…except…finally语句,使代码更加简洁;
  • context:通常是表达式,返回一个对象;
  • var变量:用来保存context返回的对象,可以是单个值或元组;
  • with_suite:使用变量var对context返回对象进行各种操作的代码段

二、示例

  1. # 查看文件内容
  2. XZ:learn xz$ cat with.txt
  3. with...as...
  4. 12345
  5. abcde
  6. In [2]: with open('with.txt','r+') as f:
  7. ...: for line in f.readlines():
  8. ...: print(line)
  9. ...: print('with is closed : ', f.closed)
  10. ...:
  11. ...:
  12. with...as...
  13. 12345
  14. abcde
  15. with is closed : True
  • 打开文本with.txtf变量接收文件对象返回的对象;
  • 读取文本中的内容,逐行打印;
  • with中的代码执行完成后,会自动关闭文件;
  • 如果with语句中没有做try...except异常处理,出现错误时会直接将异常交给Python解释器抛出,不会自动关闭文件,如果做了try...except异常处理,出现异常时,会自动关闭文件,再抛出异常。

三、原理

  1. with语句实质上是上下文管理
  • 上下文管理协议:包含2个方法:__enter____exit__
  • 支持该协议的对象,要实现这2个方法,才能被with语句进行操作。
  1. 上下文管理器
  • 定义执行with语句时建立的运行时上下文,负责执行with语句上下文的进入和退出操作;
  • 进入上下文管理器:调用管理器__enter__方法,如果设置了as var语句,变量var接受__enter__方法的返回值;
  • 退出上下文管理器:调用管理器的__exit__方法。

四、应用场景

  1. 文件操作
  2. 进程线程之间互斥对象,如互斥锁
  3. 自定义的支持上下文的其它操作

五、我的实践

  1. """
  2. with语句处理异常
  3. 我们知道使用try-except-finally语句可以处理异常,接下来我们介绍使用with语句处理与异常相关的工作
  4. with语句支持创建资源,抛出异常,释放资源等操作,并且代码简洁。
  5. with语句格式
  6. with 上下文表达式 [as 资源对象]: 对象操作 说明:
  7. 上下文表达式,返回一个上下文管理对象
  8. 如果指定了as语句,该对象并不赋值给as子句中的资源对象,而是将上下文管理器的__enter__()方法的返回值赋值给了资源对象。
  9. 资源对象可以是单变量,也可以是元组。
  10. 使用with语句操作文件对象
  11. """
  12. with open("test.txt") as file:
  13. for aline in file:
  14. print(aline)
  15. """
  16. 解释说明: 这段代码使用with语句打开文件,如果顺利打开,则将文件对象赋值给file,然后用for语句遍历打印文件的每一行。
  17. 当文件操作结束后,with语句关闭文件。如果这段代码运行过程中发生异常,with也会将文件关闭。
  18. 这段代码使用finally语句实现如下:
  19. """
  20. try:
  21. file = open("test.txt")
  22. try:
  23. for aline in file:
  24. print(aline)
  25. except Exception as error:
  26. print(error)
  27. finally:
  28. file.close()
  29. except FileNotFoundError as err:
  30. print(err)
  31. """
  32. 我们也可以给with语句加上异常处理:
  33. """
  34. try:
  35. with open("test.txt") as file:
  36. for aline in file:
  37. print(aline)
  38. except Exception as error:
  39. print(error)
  40. """
  41. 通过对比可以发现:with语句在进行异常处理时代码简洁很多
  42. 特别说明:
  43. 不是所有的对象都可以使用with语句,只有支持上下文管理协议的对象才可以。目前支持上下文管理协议的对象如下:
  44. """
  45. # file
  46. # decimal.Context
  47. # thread.LockType
  48. # threading.BoundedSemaphore
  49. # threading.Condition
  50. # threading.Lock
  51. # threading.RLock
  52. # threading.Semaphore