Skip to main content

函数/方法/属性 getter 的惰性求值

项目描述

懒惰的评价

建造 盾牌 执照:麻省理工学院

懒惰评估函数/类方法/类属性。目标将在第一次调用时被评估一次且仅一次,一旦目标准备好并发调用将立即获得结果,并在目标引发一些异常时获得相同的异常。

特征

  • 实现了同步和异步版本。

  • 无锁!!!!(感谢 asyncio.Future 和 concurrent.futures.Future,所有操作都是原子的)

  • 分配将立即更新缓存。

  • 由于 python 不支持 await before assignment 或del. await setattr(foo, value)是一种可能的解决方法,但它引入了更多的混淆。

安装

pip install lazy-async

例子

import asyncio
from lazy_async import lazy, lazy_property, lazy_async, lazy_property_async
from threading import Thread
import time


class ExampleClass:
    def __init__(self):
        self.sync_called = 0
        self.async_called = 0
        self.prop = 'nothing'

    @lazy
    def func1(self):
        time.sleep(5)
        self.sync_called += 1
        return 'something'

    @lazy_async
    async def func2(self):
        await asyncio.sleep(5)
        self.async_called += 1
        return 'something'

    @lazy
    def func3(self):
        time.sleep(5)
        raise ValueError('SomeException')

    @lazy_async
    async def func4(self):
        await asyncio.sleep(5)
        raise ValueError('SomeException')

    @lazy_property
    def func5(self):
        time.sleep(5)
        self.sync_called += 1
        return self.prop

    @func5.setter
    def func5(self, value):
        self.prop = value

    @lazy_property_async
    async def func6(self):
        await asyncio.sleep(5)
        self.async_called += 1
        return self.prop

    @func6.setter
    def func6(self, value):
        self.prop = value

def test_something_sync():
    test_class = ExampleClass()
    test1 = dict()

    def start1():
        test1[1] = test_class.func1()

    def start2():
        time.sleep(3)
        test1[2] = test_class.func1()

    def start3():
        time.sleep(10)
        test1[3] = test_class.func1()

    Thread(target=start1).start()
    Thread(target=start2).start()
    Thread(target=start3).start()
    time.sleep(1)
    assert test1 == {}
    time.sleep(3)
    assert test1 == {}
    time.sleep(2)
    assert test1 == {1: 'something', 2: 'something'}
    time.sleep(5)
    assert test1 == {1: 'something', 2: 'something', 3: 'something'}


def test_something_async():
    test2 = dict()
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    test_class = ExampleClass()

    async def start1():
        test2[1] = await test_class.func2()

    async def start2():
        await asyncio.sleep(3)
        test2[2] = await test_class.func2()

    async def start3():
        await asyncio.sleep(10)
        test2[3] = await test_class.func2()

    async def assert1():
        await asyncio.sleep(1)
        assert test2 == {}
        await asyncio.sleep(3)
        assert test2 == {}
        await asyncio.sleep(2)
        assert test2 == {1: 'something', 2: 'something'}
        await asyncio.sleep(5)
        assert test2 == {1: 'something', 2: 'something', 3: 'something'}

    loop.run_until_complete(asyncio.gather(start1(), start2(), start3(), assert1()))

有关更多示例,请参见单元测试。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

lazy-async-0.7.ta​​r.gz (3.6 kB 查看哈希)

已上传 source