首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可调用类型的定义是什么?

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

Stack Overflow用户
提问于 2017-09-17 11:11:48
回答 2查看 7.1K关注 0票数 5

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

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

  1. 来自https://docs.python.org/3/reference/datamodel.html 可调用类型--这些类型可以应用于函数调用操作(请参阅部分调用):

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

  1. 来自https://docs.python.org/3/reference/expressions.html#calls 主值必须计算为可调用对象(用户定义的函数、内建函数、内建对象的方法、类对象、类实例的方法和--所有具有方法的对象都是可调用的)。

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

“用户定义的函数、内建函数、内建对象的方法、类对象、类实例的方法”没有__call__()方法吗?它们是可调用类型的实例吗?他们分别有哪些特定的类型?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-17 12:32:44

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

是的,完全正确。

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

要使给定的对象成为可调用对象,它必须定义__call__,函数可以这样做,例如:

代码语言:javascript
复制
def foo():
    pass
callable(foo) # True

staticmethodclassmethod的(从上一个问题继续),不要定义__call__

代码语言:javascript
复制
s = staticmethod(foo)
callable(s)  # False

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

“用户定义的函数、内建函数、内建对象的方法、类对象、类实例的方法”没有调用()方法吗?它们是可调用类型的实例吗?他们分别有哪些特定的类型?

  • 用户定义的函数(function类型,如foo)具有__call__
  • 内置函数(例如max)也有__call__,参见callable(max)
  • 内置对象的方法,是的:callable(str.isupper)
  • 类对象是的(type为它们定义了一个__call__ ):类垃圾邮件:传递>>>可调用(垃圾邮件)# True
  • 类实例的方法:Spam2类:.def do_spam(self):返回“垃圾邮件”. >>>可调用(Spam2().do_spam)# True

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

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

票数 4
EN

Stack Overflow用户

发布于 2017-09-17 11:36:19

检查可调用的定义

代码语言:javascript
复制
from collections import Callable

源代码如下:

代码语言:javascript
复制
class Callable(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __call__(self, *args, **kwds):
        return False

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Callable:
            if any("__call__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

棘手的部分是__subclasshook__,的方法,因此任何能够找到__call__方法的类都可以作为可调用的子类来处理,而不是直接从它继承。

PS:不仅__subclasshook__可以这样做,寄存器()方法还可以将另一个类注册为基类的子类。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46263435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档