‘with’ is a keyword in Python. The reserved words in Python or any other programming language are called keywords. A keyword cannot be used as a variable name, function name, or for any other type of identification. The keyword mentioned above, alongside other keywords, could change depending on the Python version.
Some additional may be added or subtracted. It is easier to identify keywords in the Python language or even confirm that ‘with’ is a keyword in the Python version you are running. You can always enter the following command in the prompt to get the list of keywords in your current version.
import keyword print(keyword.kwlist)
Upon running the above commands, you will get the following list on Python3. You can go ahead and try it on different versions of Python and note the differences.
['False', 'None', 'True',, 'for', 'from', 'global', 'if', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally','import', 'in', 'is', 'lambda',, 'return', 'try', 'while', 'with', 'yield' 'nonlocal', 'not', 'or', 'pass', 'raise']
Python uses the ‘with’ statement in its exception handling to make the code cleaner and much easier to read. It makes managing recurring resources like file streams easier. See how the ‘with’ statement results in cleaner code by looking at the example code below.
# handling of the file # 1) without using the 'with' statement file_var = open('file_path', 'w') file_var .write('Welcome to Codeunderscored !') file_var .close() # 2) without using the 'with' statement file_var = open('file_path', 'w') try: file_var .write('Welcome to Codeunderscored') finally: file_var .close() # using the 'with' statement with open('file_path', 'w') as file_var : file_var .write('Welcome to Codeunderscored !')
Note that there is no requirement to call file.close(), in contrast to the other two implementations
when a with statement is used. The with statement alone ensures proper resource acquisition and release. A glitch when processing the file.write() modifications to files do not take effect until the file is closed correctly, therefore the file.write() function in the first implementation can prevent the file from closing correctly and introduce various issues in the code.
The second method in the above example handles all exceptions, but using the with statement makes the code much shorter and legible. The with statement prevents problems and leaks by ensuring that a resource is properly relinquished when the code consuming it has finished running. As previously demonstrated, the with statement is frequently used with file streams, locks, sockets, subprocesses, telnets, and other protocols.
User-defined objects supporting the “with” expression
Nothing specific about open() makes it useable with the ‘with’ statement; user-created objects can offer the same capability. You can guarantee that you’ll never leave any resource open by supporting with statements in your objects.
You simply need to include the methods __enter__() and __exit__() in the object methods to use with statements in user-defined objects. For more information, see the example below.
#-this is a demo file writer object class CodeMsgWriter(object): def __init__(self, name_file): self. name_file = name_file def __enter__(self): self.code_file = open(self.name_file , 'w') return self.code_file def __exit__(self): self.code_file.close() # demo for using the statement 'with' with CodeMsgWriter with CodeMsgWriter('test_file.txt') as x_file: x_file.write('Welcome to Codeunderscored')
Examine the code shown above. If you look closely, the constructor for CodeMsgWriter is what comes after the ‘with’ keyword. A CodeMsgWriter object is generated as soon as the execution enters the statement’s context, ‘with,’ and Python then runs the __enter__() method. Then, initialize the resource you want to use in the object with this __enter__() method. A descriptor of the obtained resource should always be returned by this __enter__() method.
Resource descriptors: what are they?
These are the handles the operating system gives to access to the resources that have been asked for. A file is a descriptor of the file stream resource in the following code block.
x_file = open('test_text.txt')
The __enter__() method in the CodeMsgWriter example above creates a file descriptor and returns it. In this context, the file descriptor returned by the __enter__() method is referred to as x_file. The block of the ‘with’ statement is enclosed by the block of code that uses the acquired resource.
The __exit__() method is called as soon as the code inside the with block has finished running. Further, the __exit__() method releases all acquired resources. In order to use user-defined objects with the ‘with’ statement, do as follows. The Context Manager denotes the interface of the __enter__() and __exit__() methods that support the ‘with’ statement in user-defined objects.
The module contextlib
The ‘with’ statement in user-defined objects can be supported in other ways than only a class-based context manager, as was seen above. The contextlib module offers more abstractions constructed on top of the base context manager interface. Here is how the contextlib module can be used to modify the context manager for the CodeMsgWriter object.
from contextlib import contextmanager class CodeMsgWriter(object): def __init__(self, name_of_file): self.name_of_file = name_of_file @contextmanager def open_file(self): try: x_file = open(self.name_of_file , 'w') yield file finally: x_file.close() # usage msg_writer = CodeMsgWriter('txt_file.txt') with msg_writer.open_file() as txt_file: txt_file.write('Welcome to Codeunderscored')
The method open_file() in this code sample is a generator function due to the yield statement in its definition. A resource descriptor with the name file is created when the open_file() function is used. The variable txt_file used to represent this resource descriptor here is then supplied to the caller. The open_file() method is called again once the code inside the with block has been run.
The yield statement’s code is run after the open_file() function resumes its execution. This section of the code, which follows the yield statement, releases the resources that have been acquired. In this case, the @contextmanager is a decorator.
Internally, the context managers’ former class-based and generator-based implementations are identical. The latter requires understanding generators, decorators, and yield, even though it appears more accessible.
Example: Using the ‘with’ Keyword
The try-finally strategy for managing file stream resources may be seen in the code block below.
txt_file = open('file-path', 'w') try: txt_file.write('Coding in Python') finally: txt_file.close()
Normally, you’d want to write to a file using this method, but the with statement provides a more streamlined solution:
with open('file-path', 'w') as txt_file: txt_file.write('Coding in Python')
Our writing procedure is condensed to only two lines, thanks to the ‘with’ statement.
Example: Using the ‘with’ keyword on Database CRUD operations
CRUD operations on databases need the ‘with’ Keyword. This sample demonstrates how to fetch users from an SQLite database:
def fetch_all_users(): with sqlite3.connect('db/users.db') as conn: cursor = conn.cursor() cursor.execute("SELECT * FROM user ORDER BY id desc") all_users = cursor.fetchall() return all_users
An SQLite database is queried, and its contents are returned using ‘with’ in this case.
Conclusion
With is among the reserved words that cannot be used as variable names, function names, or other identifiers in the Python programming language. It is at the core of the simplification of exception handling in Python. Python’s with statement is also used for handling exceptions and managing resources. Working with file streams is where you’d most likely find it in use. For instance, the statement ensures that if an error is raised, the file stream process stops correctly rather than blocking other processes.
The execution of a code block is contained within the methods specified by the context manager using the ‘with’ statement. Additionally, the Context Manager class implements the __enter__ and __exit__ methods. The __exit__ method is called after the nested block when the with statement is used to ensure this. This idea is comparable to the try…finally block technique.