《流畅的Python》第十八章学习笔记

2021-03-10 12:08:49 浏览数 (1)

并发是指一次处理多件事。 并行是指一次做多件事。 二者不同,但是有联系。 一个关于结构,一个关于执行。 并发用于制定方案,用来解决可能(但未必)并行的问题。

使用线程实现文本式旋转指针

代码语言:javascript复制
# -*- coding: utf-8 -*-
# @Time    : 2021/3/4 下午9:38
# @Author  : zhongxin
# @Email   : 490336534@qq.com
# @File    : spinner_thread.py

import threading
import itertools
import time
import sys


class Signal:
    go = True


def spin(msg, signal):
    write, flush = sys.stdout.write, sys.stdout.flush
    for char in itertools.cycle('|/-\'):
        status = char   ' '   msg
        write(status)
        flush()
        write('x08' * len(status))
        time.sleep(.1)
        if not signal.go:
            break
    write(' ' * len(status)   'x08' * len(status))


def slow_function():
    time.sleep(3)
    return 42


def supervisor():
    signal = Signal()
    spinner = threading.Thread(target=spin, args=('thinking!', signal))
    print('spinner object:', spinner)
    spinner.start()
    result = slow_function()
    signal.go = False
    spinner.join()
    return result


def main():
    result = supervisor()
    print('Answer:', result)


if __name__ == '__main__':
    main()

文本式旋转指针

使用协程实现文本旋转指针

代码语言:javascript复制
# -*- coding: utf-8 -*-
# @Time    : 2021/3/4 下午9:51
# @Author  : zhongxin
# @Email   : 490336534@qq.com
# @File    : spinner_asyncio.py
import asyncio
import itertools
import sys


class Signal:
    go = True


@asyncio.coroutine
def spin(msg):
    write, flush = sys.stdout.write, sys.stdout.flush
    for char in itertools.cycle('|/-\'):
        status = char   ' '   msg
        write(status)
        flush()
        write('x08' * len(status))
        try:
            yield from asyncio.sleep(.1)
        except asyncio.CancelledError:
            break
    write(' ' * len(status)   'x08' * len(status))


@asyncio.coroutine
def slow_function():
    yield from asyncio.sleep(3)
    return 42


@asyncio.coroutine
def supervisor():
    spinner = asyncio.create_task(spin('thinking!'))
    print('spinner object:', spinner)
    result = yield from slow_function()
    spinner.cancel()
    return result


def main():
    loop = asyncio.get_event_loop()
    result = loop.run_until_complete(supervisor())
    loop.close()
    print('Answer:', result)


if __name__ == '__main__':
    main()

⚠️协程的优势:协程是可以暂停和恢复的函数

回调地狱

如果一个操作需要依赖之前操作的结果,那就得嵌套回调。

代码语言:javascript复制
def stage1(res1):
    res2 = step1(res1)
    api2(res2, stage2)


def stage2(res2):
    res3 = step2(res2)
    api3(res3, stage3)


def stage3(res3):
    step3(res3)


api1(res1, stage1)

使用协程

代码语言:javascript复制
import asyncio

@asyncio.coroutine
def stage(res1):
    res1 = yield from api1(res1)
    req2 = step1(res1)

    res2 = yield from api2(req2)
    req3 = step2(res2)

    res3 = yield from api3(req3)
    step3(res3)

0 人点赞