首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是"callable"?

什么是"callable"?
EN

Stack Overflow用户
提问于 2008-09-21 23:34:33
回答 12查看 303.1K关注 0票数 342

现在what a metaclass is已经很清楚了,有一个相关的概念,我一直在使用,但并不知道它的真正含义。

我想每个人都犯过一次括号错误,导致了一个"object is not callable“异常。更重要的是,使用__init____new__ lead想知道这个该死的__call__能用来做什么。

你能给我一些解释,包括魔法方法的例子吗?

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2008-09-21 15:44:23

callable是可以调用的任何东西。

built-in (PyCallable_Check in objects.c)检查参数是否为:

  • 具有__call__方法或

结构的类的实例所属的类型具有非空结构(c

  • )成员,该成员指示可调用性,否则(如在函数、方法等中)

名为__call__的方法为(according to the documentation)

实例作为函数‘’调用‘’时调用的

示例

代码语言:javascript
复制
class Foo:
  def __call__(self):
    print 'called'

foo_instance = Foo()
foo_instance() #this is calling the __call__ method
票数 340
EN

Stack Overflow用户

发布于 2008-09-22 15:04:54

来自Python的源代码object.c

代码语言:javascript
复制
/* Test whether an object can be called */

int
PyCallable_Check(PyObject *x)
{
    if (x == NULL)
        return 0;
    if (PyInstance_Check(x)) {
        PyObject *call = PyObject_GetAttrString(x, "__call__");
        if (call == NULL) {
            PyErr_Clear();
            return 0;
        }
        /* Could test recursively but don't, for fear of endless
           recursion if some joker sets self.__call__ = self */
        Py_DECREF(call);
        return 1;
    }
    else {
        return x->ob_type->tp_call != NULL;
    }
}

上面写着:

如果一个对象是某个类的实例,则它是可调用的当且仅当它具有x->ob_type->tp_call != NULL时,

  1. 是可调用的__call__ x

tp_call field的描述

ternaryfunc tp_call一个可选的指针,指向实现对象调用的函数。如果对象不可调用,则该值应为NULL。签名与PyObject_Call()的签名相同。此字段由子类型继承。

您可以始终使用内置的callable函数来确定给定对象是否可调用;或者更好的做法是调用它并在以后捕获TypeError。在Python3.0和3.1中删除了callable,请使用callable = lambda o: hasattr(o, '__call__')isinstance(o, collections.Callable)

例如,一个简单的缓存实现:

代码语言:javascript
复制
class Cached:
    def __init__(self, function):
        self.function = function
        self.cache = {}

    def __call__(self, *args):
        try: return self.cache[args]
        except KeyError:
            ret = self.cache[args] = self.function(*args)
            return ret    

用法:

代码语言:javascript
复制
@Cached
def ack(x, y):
    return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1) 

来自标准库、文件site.py、内置exit()quit()函数定义的示例:

代码语言:javascript
复制
class Quitter(object):
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return 'Use %s() or %s to exit' % (self.name, eof)
    def __call__(self, code=None):
        # Shells like IDLE catch the SystemExit, but listen when their
        # stdin wrapper is closed.
        try:
            sys.stdin.close()
        except:
            pass
        raise SystemExit(code)
__builtin__.quit = Quitter('quit')
__builtin__.exit = Quitter('exit')
票数 91
EN

Stack Overflow用户

发布于 2008-09-26 13:22:20

callable是一个对象,允许您使用圆括号()并最终传递一些参数,就像函数一样。

每次定义函数时,python都会创建一个可调用的对象。在示例中,您可以用以下方式定义函数func (相同):

代码语言:javascript
复制
class a(object):
    def __call__(self, *args):
        print 'Hello'

func = a()

# or ... 
def func(*args):
    print 'Hello'

你可以使用这个方法而不是像doit或者run这样的方法,我认为看到obj()比obj.doit()更清楚。

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

https://stackoverflow.com/questions/111234

复制
相关文章

相似问题

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