现在,元类是什么已经很清楚了,有一个相关的概念,我一直在使用,但不知道它的真正含义。

我想每个人都犯过一次圆括号错误,导致“对象不可调用”异常。更重要的是,使用__init__和__new__会导致想知道这个该死的__call__可以用来做什么。

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


当前回答

Callable是带有方法的“内置函数或方法”的类型或类 调用

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

例子: Print是一个可调用对象。使用内置函数调用 当你调用print函数时,Python创建一个print类型的对象,并调用它的方法调用,如果有参数,则传递参数。

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

其他回答

在Python中,可调用对象是一个类型具有__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

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

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

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

让我反过来解释:

考虑这个……

foo()

... 作为语法上的糖:

foo.__call__()

其中foo可以是任何响应__call__的对象。当我说任何对象时,我指的是内置类型,你自己的类和它们的实例。

对于内置类型,当你写:

int('10')
unicode(10)

你实际上是在做:

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

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

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