Python context manager

This article is translated fromhttps://www.pythontutorial.net/advanced-python/python-context-managers/

Python context manager

Summary: In this tutorial, you will learn about Python context managers and how to use them effectively

Introduction to Python context managers

A context manager is an object implemented in a with statement that defines a runtime context< /strong>.

Let’s start with a simple example to understand the concept of a context manager.

Suppose you have a file called data.txt that contains an integer 100.

The following program reads the data.txt file, converts its contents to numbers, and displays the result on standard output.

f = open('data.txt')
data = f. readlines()

# Convert the number to an integer and display it
print(int(data[0]))

f. close()

The code is simple and straightforward.

However, data.txt may contain data that cannot be converted to numbers. In this case, the code will cause an exception.

For example, if data.txt contained the string ‘100’ instead of the number 100, you would get the following error.

ValueError: invalid literal for int() with base 10: '100'

Because of this exception, Python may not be able to close the file properly.

To get around this, you might use the try…except…finally statement.

try:
    f = open('data.txt')
    data = f. readlines()
    print(int(data[0]))

except ValueError as error:
    print(error)

finally:
    f. close()

Since the code in the finally block is always executed, the code will always close the file properly.

This solution works as expected. However, it is quite verbose.

Therefore, Python provides you with a better method, allowing you to automatically close the file when you are done with it.

This is where context managers come into play.

The following shows how to use the context manager to process the data.txt file.

with open('data.txt') as f:
    data = f. readlines()
    print(int(data[0]))

In this example, we use the open() function and the with statement. After the with statement ends, Python will automatically close the file.

Python with statement

The following is the typical syntax of the with statement:

with context as ctx:
    # use the object
    
# context is cleaned up

How it works.

  • When Python encounters a with statement, it creates a new context object. The context can optionally return a object .

  • Python automatically cleans up the context after a with block.

  • The ctx and with statements have the same scope. This means you can access ctx inside or after a with statement.

The following shows how to access the f variable after the with statement

with open('data.txt') as f:
    data = f. readlines()
    print(int(data[0]))


print(f.closed) # True

Python context manager protocol

Python context managers work based on the context manager protocol.

The context manager protocol has the following methods.

  • __enter__() – Sets the context, optionally returning some object.

  • __exit__() – Cleans up the object.

If you want a class to support the context manager protocol, you need to implement these two methods.

Suppose ContextManager is a class that supports the context manager protocol.

Here’s how to use the ContextManager class:

with ContextManager() as ctx:
    # do something

# done with the context

When you use the ContextManager class in a with statement, Python implicitly creates a ContextManager class instance ( instance ) and automatically calls the __enter__() method on the instance.

The __enter__() method can optionally return an object. If so, Python will assign the returned object to ctx .

Note that ctx refers to the object returned by the __enter__() method. It does not refer to an instance of the ContextManager class.

If an exception occurs within the with block or after the with block, Python will call exit on the instance object strong>() method.

Python-Context-Manager.png

Functionally, the with statement is equivalent to the try…finally statement below.

instance = ContextManager()
ctx = instance.__enter__()

try:
    # do something with the text
finally:
    # do with the context
    instance.__exit__()

__enter__()method

In the __enter__() method, you can perform the necessary steps to set up the context.

Additionally, you can return an object from the __enter__() method.

__exit__()method

Python always executes the __exit__() method, even if an exception occurs within a with block.

The __exit__() method accepts three parameters: exception type, exception value, and traceback object. All of these parameters will be None if no exception occurs.

def __exit__(self, ex_type, ex_value, ex_traceback):
    ...

The __exit__() method returns a Boolean value, True or False .

If the return value is True, Python will silence any exception. Otherwise, it doesn’t silence the exception.

Application of Python context manager

As you can see from the previous examples, a common use of context managers is to automatically open and close files.

However, you can use context managers in many other situations.

1) Open – Close

If you want to automatically open and close a resource, you can use a context manager.

For example, you can use a context manager to open a socket and close it.

2) Lock-release

Context managers can help you manage object locks more efficiently. They allow you to acquire a lock and release it automatically.

Context managers also help you work in situations where start and stop phases are required.

For example, you can use a context manager to start a timer and stop it automatically.

3) change – reset

Context managers can be used for change and reset scenarios

For example, your application needs to connect to multiple data sources. And it has a default connection.

To connect to another data source:

  • First, use the context manager to change the default connection to a new one.

  • Second, let the new connection start working.

  • Third, once you’re done working on the new connection, reset it to the default connection.

Implements the Python context management protocol

A simple implementation of the open() function using the context management protocol is shown below.

class File:
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode

    def __enter__(self):
        print(f'Opening the file {<!-- -->self.filename}.')
        self.__file = open(self.filename, self.mode)
        return self.__file

    def __exit__(self, type, value, traceback):
        print(f'Closing the file {<!-- -->self.filename}.')
        if not self.__file.closed:
            self.__file.close()

        return False

With File('data.txt', 'r') as f:
    print(int(next(f)))

How it works.

  • First, initialize filename and mode in the __init__() method.

  • Second, open the file and return the file object in the __enter__() method.

  • Third, close the file if it was opened in the __exit__() method.

Using the Python context manager to implement start and stop patterns

The following defines a Timer class that supports the context management protocol.

from time import perf_counter

class Timer:
    def __init__(self):
        self. elapsed = 0

    def __enter__(self):
        self.start = perf_counter()
        return self

    def __exit__(self, exc_type, exc_value, exc_traceback):
        self. stop = perf_counter()
        self. elapsed = self. stop - self. start
        return False

How it works.

  • First, import perf_counter from the time module.

  • Second, start the timer in the __enter__() method.

  • Third, stop the timer in the __exit__() method and return the elapsed time.

Now, you can use the Timer class to measure the time it takes to calculate the Fibonacci function with a parameter of 1000, one million times.

def fibonacci(n):
    f1 = 1
    f2 = 1
    for i in range(n-1):
        f1, f2 = f2, f1 + f2

    return f1


with Timer() as timer:
    for _ in range(1, 1000000):
        fibonacci(1000)

print(timer. elapsed)

Summary

  • When executed within a with statement, a Python context manager is used to define the runtime context.

  • Implement the __enter__() and __exit__() methods to support the context management protocol.
    (full text)

Some pictures are from the source website, intruded and deleted.

In view of my lack of talent and learning, it is inevitable that there will be omissions in the translation. If you have any questions, please feel free to contact me for criticism and correction: [email protected]

I am gled fish, click here to come to my blog site:

Please indicate the translator and the original source when reprinting, and please do not use it for any commercial purposes.

syntaxbug.com © 2021 All Rights Reserved.