测试函数或方法是否正常或异步

2024-09-28 20:16:30 发布

您现在位置:Python中文网/ 问答频道 /正文

如何确定函数或方法是普通函数还是异步函数?我希望我的代码自动支持普通或异步回调,并需要一种方法来测试传递的函数类型。

async def exampleAsyncCb():
    pass

def exampleNomralCb():
    pass

def isAsync(someFunc):
    #do cool dynamic python stuff on the function
    return True/False

async def callCallback(cb, arg):
    if isAsync(cb):
        await cb(arg)
    else:
        cb(arg)

根据传递的函数类型,它应该正常运行或使用await。我尝试了各种方法,但不知道如何实现isAsync()


Tags: 方法函数代码类型asyncdefargpass
3条回答

如果不想引入另一个带有inspect的导入,也可以在asyncio中使用iscoroutine

import asyncio

def isAsync(someFunc):
    return asyncio.iscoroutinefunction(someFunc)

使用Python的inspect模块。

inspect.iscoroutinefunction(object)

Return true if the object is a coroutine function (a function defined with an async def syntax).

此函数在Python3.5之后可用。 该模块可用于Python 2,但功能较少,而且肯定没有您要寻找的功能:inspect

顾名思义,Inspect模块对于检查很多事情都很有用。文件上说

The inspect module provides several useful functions to help get information about live objects such as modules, classes, methods, functions, tracebacks, frame objects, and code objects. For example, it can help you examine the contents of a class, retrieve the source code of a method, extract and format the argument list for a function, or get all the information you need to display a detailed traceback.

There are four main kinds of services provided by this module: type checking, getting source code, inspecting classes and functions, and examining the interpreter stack.

本模块的一些基本功能包括:

inspect.ismodule(object)
inspect.isclass(object)
inspect.ismethod(object)
inspect.isfunction(object)

它还打包了检索源代码的功能

inspect.getdoc(object)
inspect.getcomments(object)
inspect.getfile(object) 
inspect.getmodule(object)

方法是直观命名的。如有需要,可在文档中找到说明。

共同例程设置了COROUTINE标志,代码标志中的位6:

>>> async def foo(): pass
>>> foo.__code__.co_flags & (2 << 6)
128   # not 0, so the flag is set.

值128作为常量存储在inspect模块中:

>>> import inspect
>>> inspect.CO_COROUTINE
128
>>> foo.__code__.co_flags & inspect.CO_COROUTINE
128

^{} function就是这样做的;测试对象是否是函数或方法(以确保有一个__code__属性)并测试该标志。请参阅source code

当然,使用inspect.iscoroutinefunction()是最具可读性的,并且保证在代码标志发生更改时继续工作:

>>> inspect.iscoroutinefunction(foo)
True

相关问题 更多 >