Added example answers for chapters 13 and 14 to fix #1

This commit is contained in:
Rick van Hattem
2022-08-31 20:49:02 +02:00
parent 1c106d776c
commit 82cf71ed1c
20 changed files with 690 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
# Create an `asyncio` wrapper class for a synchronous process
# such as file or network operations using executors
# This example shows an `AsyncioFile` class that makes your file
# operations asynchronous by running them in a separate thread.
# If your operation has a tendency to block the Python GIL you
# could also opt for using a ProcessPoolExecutor instead.
#
# Note that for real-life usage I would recommend the aiofiles
# module over this class.
import asyncio
import concurrent.futures
import functools
import pathlib
from asyncio import AbstractEventLoop
from concurrent.futures import ThreadPoolExecutor
class AsyncExecutorBase:
_executor: ThreadPoolExecutor
_loop: AbstractEventLoop
def __init__(self):
self._executor = concurrent.futures.ThreadPoolExecutor()
self._loop = asyncio.get_running_loop()
super().__init__()
def _run_in_executor(self, func, *args, **kwargs):
# Note that this method is not async but can be awaited
# because it returns a coroutine. Alternatively, we could
# have made this method async and used `await` before
# returning
return self._loop.run_in_executor(
self._executor,
functools.partial(func, *args, **kwargs),
)
class AsyncioFile(AsyncExecutorBase):
_path: pathlib.Path
def __init__(self, path: pathlib.Path):
super().__init__()
self._path = path
async def exists(self) -> bool:
return await self._run_in_executor(self._path.exists)
async def rename(self, target):
return await self._run_in_executor(
self._path.rename,
target,
)
async def read_text(self, encoding=None, errors=None):
return await self._run_in_executor(
self._path.read_text,
encoding=encoding,
errors=errors,
)
async def read_bytes(self):
return await self._run_in_executor(self._path.read_bytes)
async def write_text(self, data, encoding=None, errors=None,
newline=None):
return await self._run_in_executor(
self._path.write_text,
data,
encoding=encoding,
errors=errors,
newline=newline,
)
async def write_bytes(self, data):
return await self._run_in_executor(
self._path.write_bytes,
data,
)
async def main():
afile = AsyncioFile(pathlib.Path(__file__))
print('#' * 79)
print('Exists:', await afile.exists())
print('#' * 79)
print('Contents:')
print(await afile.read_text())
if __name__ == '__main__':
asyncio.run(main())