Python with语句
时间:2020-02-23 14:43:40 来源:igfitidea点击:
Python with语句使我们在与上下文管理器一起工作时可以编写更简单的代码。
with语句是在PEP 343下的Python 2.5中引入的。
1.什么是上下文管理器?
上下文管理器是创建和管理运行时上下文的对象。
上下文管理器的典型用法是保存和还原全局状态,锁定和解锁资源,打开和关闭文件等。
2.上下文管理器的生命周期
上下文管理器对象必须定义enter()和exit()方法。
创建运行时上下文并销毁它们时将调用这些方法。
3.为什么我们需要带with语句的Python?
当我们必须使用文件时,我们必须首先打开它。
它为文件创建一个运行时上下文管理器。
工作完成后,我们必须手动关闭文件,以便上下文管理器正确终止。
我们通常使用try-except块来处理文件,最后使用块来关闭文件。
这样可以确保即使try块引发错误也可以关闭文件。
try: txt_file = open("abc.txt") # do some operations txt_file.close() except FileNotFoundError as e: print(e) finally: txt_file.close()
执行with块中的代码时,Python with语句负责调用上下文管理器的exit()方法。
让我们使用with语句重写上面的代码。
with open("abc.txt") as file: # do some operations print("Done")
该代码更易于阅读,我们不必担心每次都关闭文件。
4. Python与语句自定义上下文管理器示例
我们可以通过实现enter()和exit()方法来定义自己的自定义上下文管理器。
class MyContext: def __init__(self): print("init method of MyContext") def __enter__(self): print("entering context of MyContext") def __exit__(self, exc_type, exc_val, exc_tb): print("exit context of MyContext") with MyContext() as my_context: print("my_context code")
输出:
init method of MyContext entering context of MyContext my_context code exit context of MyContext
上下文管理器已初始化。
然后,为上下文管理器对象调用__enter __()方法。
with块中的代码被执行。
最后,调用上下文管理器的__exit __()方法。
5.带有打开文件的Python
Python 3.1增强了with语句,以支持多个上下文管理器。
让我们看看如何使用with语句打开多个文件。
with open("abc.txt") as file1, open("abc.txt") as file2: pass
上面的代码等效于多个嵌套的with语句。
with open("abc.txt") as file1: with open("abc.txt") as file2: pass
6.具有语句异常情况的Python
如果with块中引发了异常,则将其类型,值和回溯作为参数传递给__exit __()。
如果__exit __()方法返回False,则重新引发异常。
class MyContext: def __init__(self): print("init method of MyContext") def __enter__(self): print("entering context of MyContext") def __exit__(self, exc_type, exc_val, exc_tb): print(f'exit context of MyContext - {exc_type} :: {exc_val} :: {exc_tb}') return False with MyContext() as my_context: print("my_context code") raise TypeError("TypeError inside with block")
输出:
init method of MyContext entering context of MyContext my_context code exit context of MyContext - <class 'TypeError'> :: TypeError inside with block :: <traceback object at 0x1044e8f48> Traceback (most recent call last): File "/Users/hyman/Documents/PycharmProjects/hello-world/theitroad/with_statement.py", line 32, in <module> raise TypeError("TypeError inside with block") TypeError: TypeError inside with block
如果__exit __()方法返回True,则使用该异常并继续正常执行。
class MyContext: def __init__(self): print("init method of MyContext") def __enter__(self): print("entering context of MyContext") def __exit__(self, exc_type, exc_val, exc_tb): print(f'exit context of MyContext - {exc_type} :: {exc_val} :: {exc_tb}') return True with MyContext() as my_context: print("my_context code") raise TypeError("TypeError inside with block") print("Done")
输出:
init method of MyContext entering context of MyContext my_context code exit context of MyContext - <class 'TypeError'> :: TypeError inside with block :: <traceback object at 0x102149e08> Done