Callable 和 FunctionType 之间的区别

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

我正在尝试正确输入提示我的代码,并遇到了 CallableFunctionType

from typing import Callable
def my_func() -> Callable:
    f = lambda: _
    return f

result = my_func()
type(result)  # <class 'function'>
isinstance(result, Callable)  # True

from types import FunctionType
def my_func() -> FunctionType
    f = lambda: ...
    return f

result = my_func()
type(result)  # <class 'function'>
isinstance(result, FunctionType)  # True

我能想到的一个可能的情况是区分常规可调用对象和基于类的可调用对象,如下所示

class C:
    def __call__(self):
        pass

def my_func() -> Callable:
    c = C()
    return c

result = my_func()
type(result)  # <class 'function'>
isinstance(result, Callable)  # True
isinstance(result, FunctionType)  # False

它们之间有什么区别以及何时我必须使用其中一种而不是另一种?

python python-3.x python-typing callable-object
1个回答
1
投票

types.FunctionType
cpython/Lib/types.py#L11-L12中动态定义为最简单函数的类型。

def _f(): pass
FunctionType = type(_f)
另一方面,

typing.Callable
被定义为包装的
collections.abc.Callable
,如果使用python >= 3.9,则a)应该直接使用,b)本身在cpython/Lib/_collections_abc.py#L534中定义-L548 作为具有
__call__
方法的东西。

class Callable(metaclass=ABCMeta):  # NOTE: I'm skipping most of the definition

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Callable:
            return _check_methods(C, "__call__")
        return NotImplemented

您已经正确地强调了几乎任何东西都可以是可调用的,只需要给它一个

__call__
方法,另一方面,类永远不会是函数。

在大多数情况下,您应该使用

Callable
,除非您完全确定您只需要一个函数

此外,您可以(并且应该)键入

Callable
的参数和返回值,例如:

  • Callable[[], None]
    -- 无参数,返回
    None
    (例如
    lambda: None
  • Callable[[int, int], int]
    -- 两个
    int
    参数,返回一个
    int
  • Callable[..., None]
    -- 任何参数,返回
    None
    ,(例如
    print
    )。
© www.soinside.com 2019 - 2024. All rights reserved.