美文网首页
with与async with

with与async with

作者: MononokeHime | 来源:发表于2019-08-12 14:48 被阅读0次

应用场景:

  • 文件的读写
  • 数据库的读写操作
  • Flask的上下文管理

上下文管理协议:当使用with语句时,解释器会自动调用 __enter__,__exit__

class Sample:
    def __enter__(self):
        print('enter')  #进入资源
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit')  #释放资源
    def do_something(self):
        print('do something')

with Sample() as sample:   
    sample.do_something()

输出

enter
do something
exit

进入with语句,调用__enter__;退出with语句,调用__exit__

事实上sample并不是sample=Sample(),而是__enter__返回的对象,即如果__enter__没有return,sample将为None。

exc_type:异常类型;exc_val:异常值;exc_tb:traceback。如果with语句中有异常发生,__exit__中会收集这些异常信息。

async with

async with的用法和with一样,只是内部使用__aenter____aexit__来定义上下文。这样我们就能在上下文中使用异步编程。

class Lock(object):
    def __init__(self, redis_client, key="", ttl=60, timeout=30, interval=0.03, is_wait=True):
        """
        :param key:
        :param ttl: expire time(锁最大过期时间) / s
        :param timeout: timeout(阻塞最大时间) / s
        :param interval: sleep interval(睡眠间隔) / s
        :return:
        Usage::

            with Lock('my_lock') as lock:
                pass
        """
        self.redis_client = redis_client
        self.key = f"redis:lock:{key}"
        self.ttl = ttl
        self.timeout = timeout
        self.interval = interval
        self.value = uuid.uuid1().hex
        self.is_wait = is_wait

    async def __aenter__(self):
        res, wait_times = await self.async_acquire()
        return wait_times

    async def __aexit__(self, exc_type, exc, tb):
        self.release()

    async def async_acquire(self):
        timeout = self.timeout
        wait_times = 0  # 尝试获取锁的次数
        if timeout == 0:
            while True:
                wait_times += 1
                # redis操作理论上也需要改为异步,由于redis操作很快,暂时先用同步
                if self.redis_client.set(self.key, self.value, ex=self.ttl, nx=True):
                    return True, wait_times
                if not self.is_wait:  # 不等待锁
                    raise TooFrequentException('Operation is too frequent')
                await asyncio.sleep(self.interval)
        else:
            while timeout >= 0:
                wait_times += 1
                if self.redis_client.set(self.key, self.value, ex=self.ttl, nx=True):
                    return True, wait_times
                timeout -= self.interval
                if not self.is_wait:  # 不等待锁
                    raise TooFrequentException('Operation is too frequent')
                await asyncio.sleep(self.interval)
            raise LockTimeout("Timeout whilst waiting for lock")

相关文章

  • Koa-------学习(2)async/await

    async与await一般都是同时出现.async是异步的简写,而await可以堪称async wait的简写 a...

  • promise 与 async await 异步之美

    一眼看懂promise与async await async和await在干什么,async用于申明一个functi...

  • with与async with

    应用场景: 文件的读写 数据库的读写操作 Flask的上下文管理 上下文管理协议:当使用with语句时,解释器会自...

  • JavaScript Async/Await

    笔记 What is Async/Await? Async/Await基于Promise, 并可以很好的与基于Pr...

  • 同步执行

    Promise 与async 请求结束后执行then ()

  • async与await总结

    async与await两种语法结合可以让异步代码像同步代码一样。 一、async函数 async函数的返回值为pr...

  • flutter-async和await原理解析

    一 . async await 与 Future 在异步调用中有三个关键词,async、await、Futur...

  • async函数

    1.async语法 async函数自带执行器。async函数的执行,与普通函数一模一样 await表示紧跟在后面的...

  • Celery进阶二

    任务调度delay&apply_async delay与apply_async都是用来做任务调度,但如果查看del...

  • Flutter future 与 async await 的区别

    1、Flutter future 与 async await 的区别/异同 Flutter future 与 as...

网友评论

      本文标题:with与async with

      本文链接:https://www.haomeiwen.com/subject/yslujctx.html