Skip to content

Commit 4aa3f7d

Browse files
authored
Merge pull request #676 from realpython/python-with-statement
Sample code for the article on the `with` statement
2 parents cfba954 + e2e3cc9 commit 4aa3f7d

File tree

12 files changed

+175
-0
lines changed

12 files changed

+175
-0
lines changed

python-with-statement/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Python's with Statement: Manage External Resources Safely
2+
3+
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/).
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class HelloContextManager:
2+
def __enter__(self):
3+
print("Entering the context...")
4+
return "Hello, World!"
5+
6+
def __exit__(self, exc_type, exc_value, exc_tb):
7+
print("Leaving the context...")
8+
if isinstance(exc_value, IndexError):
9+
# Handle IndexError here...
10+
print(f"An exception occurred in your with block: {exc_type}")
11+
print(f"Exception message: {exc_value}")
12+
return True
13+
14+
15+
with HelloContextManager() as hello:
16+
print(hello)
17+
hello[100]
18+
19+
print("Continue normally from here...")

python-with-statement/hello.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class HelloContextManager:
2+
def __enter__(self):
3+
print("Entering the context...")
4+
return "Hello, World!"
5+
6+
def __exit__(self, exc_type, exc_value, exc_tb):
7+
print("Leaving the context...")
8+
if isinstance(exc_value, IndexError):
9+
print(f"An exception occurred in with block: {exc_type}")
10+
print(f"Exception message: {exc_value}")
11+
return True
12+
return False
13+
14+
15+
with HelloContextManager() as hello:
16+
print(hello)
17+
# hello[100]
18+
19+
print("Continue normally from here...")

python-with-statement/indenter.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Indenter:
2+
def __init__(self):
3+
self.level = -1
4+
5+
def __enter__(self):
6+
self.level += 1
7+
return self
8+
9+
def __exit__(self, *_):
10+
self.level -= 1
11+
12+
def print(self, text):
13+
print(" " * self.level + text)

python-with-statement/precision.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from decimal import Decimal, localcontext
2+
3+
with localcontext(prec=42):
4+
print(Decimal("1") / Decimal("42"))
5+
6+
7+
print(Decimal("1") / Decimal("42"))

python-with-statement/redirect.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import sys
2+
3+
4+
class StandardOutputRedirector:
5+
def __init__(self, new_output):
6+
self.new_output = new_output
7+
8+
def __enter__(self):
9+
self.std_output = sys.stdout
10+
sys.stdout = self.new_output
11+
12+
def __exit__(self, *_):
13+
sys.stdout = self.std_output
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import os
2+
3+
with os.scandir(".") as dir_entries:
4+
for entry in dir_entries:
5+
print(entry.name, "->", entry.stat().st_size, "bytes")
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import asyncio
2+
3+
import aiohttp
4+
5+
6+
async def check(url):
7+
async with aiohttp.ClientSession() as session:
8+
async with session.get(url) as response:
9+
print(f"{url}: status -> {response.status}")
10+
html = await response.text()
11+
print(f"{url}: type -> {html[:17].strip()}")
12+
13+
14+
async def main():
15+
await asyncio.gather(
16+
check("https://realpython.com"),
17+
check("https://pycoders.com/"),
18+
)
19+
20+
21+
asyncio.run(main())
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import asyncio
2+
3+
import aiohttp
4+
5+
6+
class AsyncSession:
7+
def __init__(self, url):
8+
self._url = url
9+
10+
async def __aenter__(self):
11+
self.session = aiohttp.ClientSession()
12+
response = await self.session.get(self._url)
13+
return response
14+
15+
async def __aexit__(self, *_):
16+
await self.session.close()
17+
18+
19+
async def check(url):
20+
async with AsyncSession(url) as response:
21+
print(f"{url}: status -> {response.status}")
22+
html = await response.text()
23+
print(f"{url}: type -> {html[:17].strip()}")
24+
25+
26+
async def main():
27+
await asyncio.gather(
28+
check("https://realpython.com"),
29+
check("https://pycoders.com"),
30+
)
31+
32+
33+
asyncio.run(main())

python-with-statement/timer.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from time import perf_counter, sleep
2+
3+
4+
class Timer:
5+
def __enter__(self):
6+
self.start = perf_counter()
7+
8+
def __exit__(self, *_):
9+
end = perf_counter()
10+
print(f"Elapsed time: {end - self.start:.4f} seconds")
11+
12+
13+
with Timer():
14+
# The code to measure goes here...
15+
sleep(0.5)

0 commit comments

Comments
 (0)