diff --git a/python-with-statement/README.md b/python-with-statement/README.md new file mode 100644 index 0000000000..eef68ec0e3 --- /dev/null +++ b/python-with-statement/README.md @@ -0,0 +1,3 @@ +# Python's with Statement: Manage External Resources Safely + +This folder provides the code examples for the Real Python tutorial [Python's with Statement: Manage External Resources Safely](https://realpython.com/python-with-statement/). diff --git a/python-with-statement/exc_handling.py b/python-with-statement/exc_handling.py new file mode 100644 index 0000000000..d5065998b8 --- /dev/null +++ b/python-with-statement/exc_handling.py @@ -0,0 +1,19 @@ +class HelloContextManager: + def __enter__(self): + print("Entering the context...") + return "Hello, World!" + + def __exit__(self, exc_type, exc_value, exc_tb): + print("Leaving the context...") + if isinstance(exc_value, IndexError): + # Handle IndexError here... + print(f"An exception occurred in your with block: {exc_type}") + print(f"Exception message: {exc_value}") + return True + + +with HelloContextManager() as hello: + print(hello) + hello[100] + +print("Continue normally from here...") diff --git a/python-with-statement/hello.py b/python-with-statement/hello.py new file mode 100644 index 0000000000..7d0a1235f3 --- /dev/null +++ b/python-with-statement/hello.py @@ -0,0 +1,19 @@ +class HelloContextManager: + def __enter__(self): + print("Entering the context...") + return "Hello, World!" + + def __exit__(self, exc_type, exc_value, exc_tb): + print("Leaving the context...") + if isinstance(exc_value, IndexError): + print(f"An exception occurred in with block: {exc_type}") + print(f"Exception message: {exc_value}") + return True + return False + + +with HelloContextManager() as hello: + print(hello) + # hello[100] + +print("Continue normally from here...") diff --git a/python-with-statement/indenter.py b/python-with-statement/indenter.py new file mode 100644 index 0000000000..a7a25532b6 --- /dev/null +++ b/python-with-statement/indenter.py @@ -0,0 +1,13 @@ +class Indenter: + def __init__(self): + self.level = -1 + + def __enter__(self): + self.level += 1 + return self + + def __exit__(self, *_): + self.level -= 1 + + def print(self, text): + print(" " * self.level + text) diff --git a/python-with-statement/precision.py b/python-with-statement/precision.py new file mode 100644 index 0000000000..68977dc45b --- /dev/null +++ b/python-with-statement/precision.py @@ -0,0 +1,7 @@ +from decimal import Decimal, localcontext + +with localcontext(prec=42): + print(Decimal("1") / Decimal("42")) + + +print(Decimal("1") / Decimal("42")) diff --git a/python-with-statement/redirect.py b/python-with-statement/redirect.py new file mode 100644 index 0000000000..b93f9744f1 --- /dev/null +++ b/python-with-statement/redirect.py @@ -0,0 +1,13 @@ +import sys + + +class StandardOutputRedirector: + def __init__(self, new_output): + self.new_output = new_output + + def __enter__(self): + self.std_output = sys.stdout + sys.stdout = self.new_output + + def __exit__(self, *_): + sys.stdout = self.std_output diff --git a/python-with-statement/scan_directory.py b/python-with-statement/scan_directory.py new file mode 100644 index 0000000000..6df7382c07 --- /dev/null +++ b/python-with-statement/scan_directory.py @@ -0,0 +1,5 @@ +import os + +with os.scandir(".") as dir_entries: + for entry in dir_entries: + print(entry.name, "->", entry.stat().st_size, "bytes") diff --git a/python-with-statement/site_checker_v1.py b/python-with-statement/site_checker_v1.py new file mode 100644 index 0000000000..1a51abbb31 --- /dev/null +++ b/python-with-statement/site_checker_v1.py @@ -0,0 +1,21 @@ +import asyncio + +import aiohttp + + +async def check(url): + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + print(f"{url}: status -> {response.status}") + html = await response.text() + print(f"{url}: type -> {html[:17].strip()}") + + +async def main(): + await asyncio.gather( + check("https://realpython.com"), + check("https://pycoders.com/"), + ) + + +asyncio.run(main()) diff --git a/python-with-statement/site_checker_v2.py b/python-with-statement/site_checker_v2.py new file mode 100644 index 0000000000..5a4bcc85c9 --- /dev/null +++ b/python-with-statement/site_checker_v2.py @@ -0,0 +1,33 @@ +import asyncio + +import aiohttp + + +class AsyncSession: + def __init__(self, url): + self._url = url + + async def __aenter__(self): + self.session = aiohttp.ClientSession() + response = await self.session.get(self._url) + return response + + async def __aexit__(self, *_): + await self.session.close() + + +async def check(url): + async with AsyncSession(url) as response: + print(f"{url}: status -> {response.status}") + html = await response.text() + print(f"{url}: type -> {html[:17].strip()}") + + +async def main(): + await asyncio.gather( + check("https://realpython.com"), + check("https://pycoders.com"), + ) + + +asyncio.run(main()) diff --git a/python-with-statement/timer.py b/python-with-statement/timer.py new file mode 100644 index 0000000000..0289a031b5 --- /dev/null +++ b/python-with-statement/timer.py @@ -0,0 +1,15 @@ +from time import perf_counter, sleep + + +class Timer: + def __enter__(self): + self.start = perf_counter() + + def __exit__(self, *_): + end = perf_counter() + print(f"Elapsed time: {end - self.start:.4f} seconds") + + +with Timer(): + # The code to measure goes here... + sleep(0.5) diff --git a/python-with-statement/writable_v1.py b/python-with-statement/writable_v1.py new file mode 100644 index 0000000000..d28c830cd1 --- /dev/null +++ b/python-with-statement/writable_v1.py @@ -0,0 +1,15 @@ +class WritableFile: + def __init__(self, file_path): + self.file_path = file_path + + def __enter__(self): + self.file_obj = open(self.file_path, mode="w") + return self.file_obj + + def __exit__(self, *_): + if self.file_obj: + self.file_obj.close() + + +with WritableFile("hello.txt") as file: + file.write("Hello, World!\n") diff --git a/python-with-statement/writable_v2.py b/python-with-statement/writable_v2.py new file mode 100644 index 0000000000..ec75c45d4b --- /dev/null +++ b/python-with-statement/writable_v2.py @@ -0,0 +1,12 @@ +from contextlib import contextmanager + + +@contextmanager +def writable_file(file_path): + file = open(file_path, mode="w") + yield file + file.close() + + +with writable_file("hello.txt") as file: + file.write("Hello, World!")