[英]How require that an abstract method is a coroutine?
How can I require that an abstract base class implement a specific method as a coroutine. 我如何要求抽象基类将特定方法实现为协程。 For example, consider this ABC:
例如,考虑以下ABC:
import abc
class Foo(abc.ABC):
@abc.abstractmethod
async def func():
pass
Now when I subclass and instantiate that: 现在,当我子类化并实例化它时:
class Bar(Foo):
def func():
pass
b = Bar()
This succeeds, although func
is not async
, as in the ABC. 尽管
func
不像ABC那样async
,但此操作成功。 What can I do so that this only succeeds if func
is async
? 我应该怎么做才能使
func
async
才能成功?
You may use __new__
and check if and how a child class has override parent's coros. 您可以使用
__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__
as well to suppress this constraint __new__
以抑制此约束 not only async
may be awaited. 不仅可以等待
async
。 For example 例如
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)
it's ok to call change
like 可以像这样调用
change
await o.change(key, value)
Not to mention __await__
in objects, other raw Futures, Tasks... 更不用说在对象,其他原始期货,任务中的
__await__
了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.