Home Backend Development Python Tutorial Detailed explanation of using the with keyword in Python

Detailed explanation of using the with keyword in Python

Mar 28, 2017 pm 03:21 PM

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()
Copy after login

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()
Copy after login

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
Copy after login

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 with

A basic with.

Expression

, its structure is as follows:

Among them: EXPR can be any expression; as VAR is optional. Its general execution process is as follows:

    Calculate EXPR and obtain a context manager.
  1. ##The exit() method of the context manager is saved for subsequent calls ##.
  2. #Call the enter() method of the context manager.

  3. If the with expression contains as VAR, the return value of EXPR is assigned to VAR.

  4. ##Execute the expression in BLOCK

  5. ##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.
  6. #Represent this process in code, as follows:

    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
    This process has several details:
  7. 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.

  8. 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

Attributes

db 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()
Copy after login
After understanding the execution process of with, this implementation is easy to understand. The implementation method introduced below is much more complicated to understand.

Using

Generators

Decorators

In 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()
Copy after login
At first glance, this implementation is simpler, but its mechanism is more complex. Take a look at its execution process:

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.
  1. with expression calls transaction(db), which actually calls the helper function. The helper function calls the generator function, which creates a generator.

  2. The helper function passes this generator to GeneratorContextManager and creates an instance object of GeneratorContextManager as the context manager.

  3. with 表达式调用实例对象的上下文管理器的 enter() 方法。

  4. enter() 方法中会调用这个生成器的 next() 方法。这时候,生成器方法会执行到 yield db 处停止,并将 db 作为 next() 的返回值。如果有 as VAR ,那么它将会被赋值给 VAR 。

  5. with 中的 BLOCK 被执行。

  6. BLOCK 执行结束后,调用上下文管理器的 exit() 方法。 exit() 方法会再次调用生成器的 next() 方法。如果发生 StopIteration 异常,则 pass 。

  7. 如果没有发生异常生成器方法将会执行 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
Copy after login

总结

Python的 with 表达式包含了很多Python特性。花点时间吃透 with 是一件非常值得的事情。

一些其他的例子

锁机制

@contextmanager
def locked(lock):
  lock.acquired()
  try:
    yield
  finally:
    lock.release()
Copy after login

标准输出重定向

@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"
Copy after login

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!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to solve the permissions problem encountered when viewing Python version in Linux terminal? How to solve the permissions problem encountered when viewing Python version in Linux terminal? Apr 01, 2025 pm 05:09 PM

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

How to efficiently copy the entire column of one DataFrame into another DataFrame with different structures in Python? How to efficiently copy the entire column of one DataFrame into another DataFrame with different structures in Python? Apr 01, 2025 pm 11:15 PM

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...

How to dynamically create an object through a string and call its methods in Python? How to dynamically create an object through a string and call its methods in Python? Apr 01, 2025 pm 11:18 PM

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 without serving_forever()? How does Uvicorn continuously listen for HTTP requests without serving_forever()? Apr 01, 2025 pm 10:51 PM

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 in project and problem-driven methods within 10 hours? How to teach computer novice programming basics in project and problem-driven methods within 10 hours? Apr 02, 2025 am 07:18 AM

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...

What are some popular Python libraries and their uses? What are some popular Python libraries and their uses? Mar 21, 2025 pm 06:46 PM

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

How to avoid being detected by the browser when using Fiddler Everywhere for man-in-the-middle reading? How to avoid being detected by the browser when using Fiddler Everywhere for man-in-the-middle reading? Apr 02, 2025 am 07:15 AM

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

See all articles