什么是“可赎回”?

时间:2008-09-21 15:34:33

标签: python callable

现在很明显what a metaclass is,我总是使用一个相关的概念而不知道它的真正含义。

我想每个人都用括号做错了,导致“对象不可调用”异常。更重要的是,使用__init____new__会让人想知道这个血腥的__call__可以用于什么。

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

12 个答案:

答案 0 :(得分:278)

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

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

  • 具有 __ call __ 方法或
  • 的类的实例
  • 是一种具有非空 tp_call (c struct)成员的类型,否则表示可训练性(例如在函数,方法等中)。

名为 __ call __ 的方法是(according to the documentation

  

当实例作为函数“调用”时调用

实施例

class Foo:
  def __call__(self):
    print 'called'

foo_instance = Foo()
foo_instance() #this is calling the __call__ method

答案 1 :(得分:76)

来自Python的来源object.c

/* 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;
    }
}

它说:

  1. 如果一个对象是某个类的实例,那么它是可调用的 iff 它具有__call__属性。
  2. 此外,对象x可以调用 iff x->ob_type->tp_call != NULL
  3. tp_call field的解释:

      

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

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

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

    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    
    

    用法:

    @Cached
    def ack(x, y):
        return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1) 
    

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

    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')
    

答案 2 :(得分:35)

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

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

class a(object):
    def __call__(self, *args):
        print 'Hello'

func = a()

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

您可以使用此方法代替 doit 运行等方法,我认为看到obj()比obj.doit()

答案 3 :(得分:30)

让我向后解释:

考虑一下......

foo()

......作为语法糖:

foo.__call__()

foo可以是响应__call__的任何对象。当我说任何对象时,我的意思是:内置类型,您自己的类及其实例。

对于内置类型,当你写:

int('10')
unicode(10)

你基本上是这样做的:

int.__call__('10')
unicode.__call__(10)

这也是你在Python中没有foo = new int的原因:你只需让类对象在__call__上返回它的实例。在我看来,Python解决这个问题的方式非常优雅。

答案 4 :(得分:11)

Callable是一个具有__call__方法的对象。这意味着你可以伪造可调用的函数或做一些像Partial Function Application这样的东西,你可以在这里添加一个函数并添加一些东西来增强它或填充一些参数,返回可以依次调用的东西(称为{{3在函数式编程圈中)。

某些排版错误会让解释程序尝试调用您不想要的内容,例如(例如)字符串。这可能会在解释器尝试执行不可调用的应用程序时产生错误。您可以通过执行类似下面的脚本的操作,在python解释器中看到这种情况。

[nigel@k9 ~]$ python
Python 2.5 (r25:51908, Nov  6 2007, 15:55:44) 
[GCC 4.1.2 20070925 (Red Hat 4.1.2-27)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 'aaa'()    # <== Here we attempt to call a string.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>> 

答案 5 :(得分:7)

很简单,“可调用”是可以像方法一样调用的东西。内置函数“callable()”将告诉您某些内容是否可以调用,以及检查调用属性。函数可以像类一样调用,类实例可以调用。详细了解herehere

答案 6 :(得分:6)

__call__使任何对象都可以作为函数调用。

此示例将输出8:

class Adder(object):
  def __init__(self, val):
    self.val = val

  def __call__(self, val):
    return self.val + val

func = Adder(5)
print func(3)

答案 7 :(得分:5)

在Python中,callable是一个类型具有__call__方法的对象:

>>> class Foo:
...  pass
... 
>>> class Bar(object):
...  pass
... 
>>> type(Foo).__call__(Foo)
<__main__.Foo instance at 0x711440>
>>> type(Bar).__call__(Bar)
<__main__.Bar object at 0x712110>
>>> def foo(bar):
...  return bar
... 
>>> type(foo).__call__(foo, 42)
42

就这么简单:)

这当然可以超载:

>>> class Foo(object):
...  def __call__(self):
...   return 42
... 
>>> f = Foo()
>>> f()
42

答案 8 :(得分:2)

这是你可以把“(args)”放在后面并期望它起作用的东西。可调用通常是方法或类。方法被调用,类被实例化。

答案 9 :(得分:2)

检查类的函数或方法是否可调用,这意味着我们可以调用该函数。

Class A:
    def __init__(self,val):
        self.val = val
    def bar(self):
        print "bar"

obj = A()      
callable(obj.bar)
True
callable(obj.__init___)
False
def foo(): return "s"
callable(foo)
True
callable(foo())
False

答案 10 :(得分:1)

callables实现__call__特殊方法,因此具有此类方法的任何对象都是可调用的。

答案 11 :(得分:1)

Callable是&#34;内置函数或方法&#34;的类型或类别。用一种方法 的呼叫

>>> type(callable)
<class 'builtin_function_or_method'>
>>>

实施例: 打印是一个可调用的对象。使用内置函数 __ call __ 当您调用 print 函数时,Python会创建一个对象类型为print ,并调用其方法 __ call __ 传递参数(如果有)。

>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>

谢谢。 问候, Maris的