使用类型提示注释使用types.FunctionType vs typing.Callable?

问题描述 投票:1回答:1

使用types.FunctionTypetyping.Callable作为类型提示注释有什么缺点或好处?

考虑以下代码......

import types
import typing

def functionA(func: types.FunctionType):
    rt = func()
    print(func.__name__)
    return rt

def functionB(func: typing.Callable):
    rt = func()
    print(func.__name__)
    return rt

我能看到的唯一区别是Callable可以是任何类型的可调用对象(函数,方法,类等),而FunctionType仅限于函数。 我忽略了什么吗?在某些情况下使用FunctionType而不是Callable有什么好处?

python python-3.x pycharm type-hinting
1个回答
1
投票

types模块早于PEP 484注释,主要是为了使运行时对对象的内省更容易。例如,要确定某个值是否为函数,可以运行isinstance(my_var, types.FunctionType)

typing模块包含专门用于辅助静态分析工具(如mypy)的类型提示。例如,假设您要指示参数必须是接受两个整数并返回str的函数。你可以这样做:

def handle(f: Callable[[int, int], str]) -> None: ...

没有办法以类似的方式使用FunctionType:它根本就不是为此目的而设计的。

这个函数签名也更灵活:它也可以接受带有__call__的对象之类的东西,因为这些对象确实是可调用的。

typing模块的内容有时也可以用类似于types内容的方式用于运行时检查,以方便:例如,做isinstance(f, Callable)工作。但是,此功能是故意限制的:故意禁止执行isinstance(f, Callable[[int, int], str])。尝试执行该检查将在运行时引发异常。

也就是说,我不认为使用typing中的任何内容执行运行时检查是一种好方法:typing模块首先用于静态分析。

出于类似的原因,我不会在类型提示中使用types模块中的任何内容。唯一的例外是如果你的函数编写的方式使得你需要接收的值特别是FunctionType的一个实例,而不是任意的可调用。

© www.soinside.com 2019 - 2024. All rights reserved.