Detailed explanation of using the with keyword in Python
This article mainly introduces the relevant information on the detailed use of the with keyword in Python. In Python, the with keyword is a good thing to manage the context protocol object for you. Friends who need it You can refer to the following
">
In Python 2.5, the with keyword was added. It makes the commonly used try...except...finally... pattern very convenient Reuse. Take a look at the most classic example:
with open('file.txt') as f: content = f.read()
In this code, no matter what happens during the execution of the code block in with, the file will eventually be closed if the code block is executed. If an exception occurs during the process, the program will first close the opened file before the exception is thrown.
Look at another example before initiating a database transaction request. When , code like this is often used:
db.begin() try: # do some actions except: db.rollback() raise finally: db.commit()
If the operation of initiating a transaction request is changed to support the with keyword, then code like this is enough:
with transaction(db): # do some actions
Below, the execution process of with is explained in detail, and the above code is implemented in two common ways.
The general execution process of withA basic with.
Expression, its structure is as follows: with EXPR as VAR:
BLOCK
- Calculate EXPR and obtain a context manager.
- ##The exit() method of the context manager is saved for subsequent calls ##.
#Call the enter() method of the context manager.
If the with expression contains as VAR, the return value of EXPR is assigned to VAR.
- ##Execute the expression in BLOCK ##Call the exit() method of the context manager if an error occurs during the execution of BLOCK. If the exception causes the program to exit, the exception's type, value and traceback (that is, the return value of sys.exc_info()) will be passed to the exit() method. Otherwise, three None will be passed.
- #Represent this process in code, as follows:
This process has several details:
mgr = (EXPR) exit = type(mgr).exit # 这里没有执行 value = type(mgr).enter(mgr) exc = True try: try: VAR = value # 如果有 as VAR BLOCK except: exc = False if not exit(mgr, *sys.exc_info()): raise finally: if exc: exit(mgr, None, None, None)
Copy after login - If there is no enter() or exit() in the context manager Either method, then the interpreter will throw an AttributeError.
After an exception occurs in BLOCK, if the exit() method returns a value that can be regarded as True, then the exception will not be thrown, and the subsequent code will continue to execute.
Next, use two methods to implement the above process.
Implementing the context manager class
The first method is to implement a class that contains an instance
Attributesdb and the methods required by the context manager enter() and exit() .
class transaction(object): def init(self, db): self.db = db def enter(self): self.db.begin() def exit(self, type, value, traceback): if type is None: db.commit() else: db.rollback()
Using
GeneratorsIn Python's standard library, there is a decorator that can get the context manager through the generator. The implementation process using the generator decorator is as follows:from contextlib import contextmanager @contextmanager def transaction(db): db.begin() try: yield db except: db.rollback() raise else: db.commit()
After the Python interpreter recognizes the yield keyword, def will create a generator Function
Replace the regular function (in the class definition I prefer to use functions instead of methods). The decorator contextmanager is called and returns a helper method, which will generate a GeneratorContextManager instance after being called. Finally, the EXPR in the with expression calls the helper function returned by the contentmanager decorator.- The helper function passes this generator to GeneratorContextManager and creates an instance object of GeneratorContextManager as the context manager.
with 表达式调用实例对象的上下文管理器的 enter() 方法。
enter() 方法中会调用这个生成器的 next() 方法。这时候,生成器方法会执行到 yield db 处停止,并将 db 作为 next() 的返回值。如果有 as VAR ,那么它将会被赋值给 VAR 。
with 中的 BLOCK 被执行。
BLOCK 执行结束后,调用上下文管理器的 exit() 方法。 exit() 方法会再次调用生成器的 next() 方法。如果发生 StopIteration 异常,则 pass 。
如果没有发生异常生成器方法将会执行 db.commit() ,否则会执行 db.rollback() 。
再次看看上述过程的代码大致实现:
def contextmanager(func): def helper(*args, **kwargs): return GeneratorContextManager(func(*args, **kwargs)) return helper class GeneratorContextManager(object): def init(self, gen): self.gen = gen def enter(self): try: return self.gen.next() except StopIteration: raise RuntimeError("generator didn't yield") def exit(self, type, value, traceback): if type is None: try: self.gen.next() except StopIteration: pass else: raise RuntimeError("generator didn't stop") else: try: self.gen.throw(type, value, traceback) raise RuntimeError("generator didn't stop after throw()") except StopIteration: return True except: if sys.exc_info()[1] is not value: raise
总结
Python的 with 表达式包含了很多Python特性。花点时间吃透 with 是一件非常值得的事情。
一些其他的例子
锁机制
@contextmanager def locked(lock): lock.acquired() try: yield finally: lock.release()
标准输出重定向
@contextmanager def stdout_redirect(new_stdout): old_stdout = sys.stdout sys.stdout = new_stdout try: yield finally: sys.stdout = old_stdout with open("file.txt", "w") as f: with stdout_redirect(f): print "hello world"
The above is the detailed content of Detailed explanation of using the with keyword in Python. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Solution to permission issues when viewing Python version in Linux terminal When you try to view Python version in Linux terminal, enter python...

When using Python's pandas library, how to copy whole columns between two DataFrames with different structures is a common problem. Suppose we have two Dats...

In Python, how to dynamically create an object through a string and call its methods? This is a common programming requirement, especially if it needs to be configured or run...

How does Uvicorn continuously listen for HTTP requests? Uvicorn is a lightweight web server based on ASGI. One of its core functions is to listen for HTTP requests and proceed...

How to teach computer novice programming basics within 10 hours? If you only have 10 hours to teach computer novice some programming knowledge, what would you choose to teach...

The article discusses popular Python libraries like NumPy, Pandas, Matplotlib, Scikit-learn, TensorFlow, Django, Flask, and Requests, detailing their uses in scientific computing, data analysis, visualization, machine learning, web development, and H

Fastapi ...

How to avoid being detected when using FiddlerEverywhere for man-in-the-middle readings When you use FiddlerEverywhere...
