可调用类型的定义是什么?

Tim*_*Tim 5 python types python-3.x callable-object

背景:我试图理解为什么静态和类方法在作为描述符时不可调用,而类的普通方法(即既不是静态也不是类方法的类方法)和不是类属性的函数都是描述符并可调用。

在Python中,可调用类型的定义是什么?

  1. 来自https://docs.python.org/3/reference/datamodel.html

    可调用类型这些是可以应用函数调用操作(请参阅“调用”部分)的类型:

    运算符是“函数调用操作”吗()?那么可调用类型是否定义为其实例()可以应用函数调用运算符的类型呢?

  2. 来自https://docs.python.org/3/reference/expressions.html#calls

    主对象必须计算为可调用对象(用户定义函数、内置函数、内置对象的方法、类对象、类实例的方法以及所有具有方法的对象 __call__()都是可调用的)。

    这是否意味着可调用类型可能有也可能没有 __call__()方法?如果一个类有__call__()方法,那么它一定是可调用类型?如果一个类没有__call__() 方法,那么它可能是也可能不是可调用类型?

    难道“用户定义函数、内置函数、内置对象的方法、类对象、类实例的方法”就没有方法吗 __call__()?它们是可调用类型的实例吗?它们分别有哪些具体类型?

谢谢。

Jim*_*ard 4

运算符是“函数调用操作”吗()?那么可调用类型是否定义为其实例()可以应用函数调用运算符的类型呢?

对,就是这样。

这是否意味着可调用类型可能有也可能没有__call__()方法?如果一个类有__call__()方法,那么它一定是可调用类型?如果一个类没有__call__()方法,那么它可能是也可能不是可调用类型?

对于给定的可调用对象,它必须定义__call__函数,例如:

def foo():
    pass
callable(foo) # True
Run Code Online (Sandbox Code Playgroud)

staticmethod's 或classmethods (继续上一个问题),不要定义__call__

s = staticmethod(foo)
callable(s)  # False
Run Code Online (Sandbox Code Playgroud)

callable本质上是做类似的事情getattr(foo, '__call__', False)

难道“用户定义函数、内置函数、内置对象的方法、类对象、类实例的方法”就没有call ( )方法吗?它们是可调用类型的实例吗?它们分别有哪些具体类型?

  • 用户定义的函数(function类型等foo)有__call__

  • 内置函数(例如max)也有__call__,请参见callable(max)

  • 内置对象的方法,是的:callable(str.isupper)

  • 类对象,是的(为它们type定义了 a ):__call__

    >>> class Spam: pass
    >>> callable(Spam) # True
    
    Run Code Online (Sandbox Code Playgroud)
  • 类实例的方法:

    >>> class Spam2: 
    ...     def do_spam(self):
    ...         return "spam"
    ...
    >>> callable(Spam2().do_spam)  # True
    
    Run Code Online (Sandbox Code Playgroud)

它们都是可调用的,因为它们定义了__call__特殊的方法。这是使对象可调用的唯一方法。

至于静态方法和类方法,虽然它们通常包装可调用对象(然后通过描述符协议公开),但它们本身不可调用,因为它们没有定义特殊__call__方法。