簡體   English   中英

如何要求抽象方法是協程?

[英]How require that an abstract method is a coroutine?

我如何要求抽象基類將特定方法實現為協程。 例如,考慮以下ABC:

import abc

class Foo(abc.ABC):
    @abc.abstractmethod
    async def func():
        pass

現在,當我子類化並實例化它時:

class Bar(Foo):
    def func():
        pass

b = Bar()

盡管func不像ABC那樣async ,但此操作成功。 我應該怎么做才能使func async才能成功?

您可以使用__new__並檢查子類是否以及如何覆蓋父類。

import asyncio
import abc
import inspect


class A:    

    def __new__(cls, *arg, **kwargs):
        # get all coros of A
        parent_coros = inspect.getmembers(A, predicate=inspect.iscoroutinefunction)

        # check if parent's coros are still coros in a child
        for coro in parent_coros:
            child_method = getattr(cls, coro[0])
            if not inspect.iscoroutinefunction(child_method):
                raise RuntimeError('The method %s must be a coroutine' % (child_method,))

        return super(A, cls).__new__(cls, *arg, **kwargs)

    @abc.abstractmethod
    async def my_func(self):
        pass


class B(A):

    async def my_func(self):
        await asyncio.sleep(1)
        print('bb')


class C(A):

    def my_func(self):
        print('cc')

async def main():
    b = B()
    await b.my_func()

    c = C()  # this will trigger the RuntimeError
    await c.my_func()


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

注意事項

  • 子類也可以重寫__new__以抑制此約束
  • 不僅可以等待async 例如

     async def _change_in_db(self, key, value): # some db logic pass def change(self, key, value): if self.is_validate(value): raise Exception('Value is not valid') return self._change_in_db(key, value) 

    可以像這樣調用change

     await o.change(key, value) 

    更不用說在對象,其他原始期貨,任務中的__await__了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM