python - 类协程的一部分不是协程。为什么?
问题描述
class Foo:
async def foo(self, a):
return a
async def bar(b):
return b
asyncio.iscoroutinefunction(functools.partial(bar, 1)) # returns True, OK
asyncio.iscoroutinefunction(functools.partial(Foo().foo, 1)) # returns False, WHY???
我需要找到一种方法将类中的协程包装成部分,以便结果也是一个协程。我怎么做?
解决方案
为什么是inspect
模块检查这个的方式。
def iscoroutinefunction(obj):
"""Return true if the object is a coroutine function.
Coroutine functions are defined with "async def" syntax.
"""
return _has_code_flag(obj, CO_COROUTINE)
如果我们看一下的定义_has_code_flag
:
def _has_code_flag(f, flag):
"""Return true if ``f`` is a function (or a method or functools.partial
wrapper wrapping a function) whose code object has the given ``flag``
set in its flags."""
while ismethod(f):
f = f.__func__
f = functools._unwrap_partial(f)
if not isfunction(f):
return False
return bool(f.__code__.co_flags & flag)
我们看到它首先尝试解包绑定的方法并获取其.func
属性(其中包含函数对象),然后再解包partial
. 最后,如果结果不是函数返回False
,则返回对底层函数__code__
属性进行标志检查的结果。
问题是while ismethod(f)
它什么都不做,因为那时它仍然是一个partial
对象。partial
然后在它从,解包 if 之后isfunction
返回,False
因为它只是那里的绑定方法。
这就是为什么。我不知道这是否可以被认为是一个错误,或者它是否是设计使然。_has_code_flag
文档字符串在其描述中省略了包装方法这一事实functools.partial
使我相信它是设计使然。
但是,您可以通过检查属性借用functools._unwrap_partial
并使用他们检查 a 的方法。coroutine
.func
def _unwrap_partial(func):
while isinstance(func, partial):
func = func.func
return func
取自这个答案:
def iscoroutinefunction_or_partial(object):
while isinstance(object, functools.partial):
object = object.func
return inspect.iscoroutinefunction(object)
推荐阅读
- java - 作为作业的一部分,我想将查询参数字符串转换为 Java 中的树对象
- java - 有没有办法让 Jedis 自动为命令方法使用连接池?
- reactjs - 我将如何在 ReactJs 中编写这个渲染方法,这是一个面试问题?
- java - 如何在 NetBeans 中解决此错误“地址已在使用中”?
- html - 滑块无法居中
- android - 如何使初始屏幕上的图片在 1 秒后出现
- python - 访问函数中分配的变量
- ios - swift中的iMessage扩展
- elasticsearch - elasticsearch percolator 可以给出单词位置吗?
- python - 熊猫数据框仅返回第一行 JSON 数据?