Added example answers for chapters 13 and 14 to fix #1
This commit is contained in:
@@ -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())
|
||||
Reference in New Issue
Block a user