What is a “callable”?
现在很清楚什么是元类了,有一个相关的概念,我一直在使用,而不知道它的真正含义。
我想每个人都犯过一次括号错误,导致了"object is not called"异常。更重要的是,使用
你能给我一些解释吗,包括魔法方法的例子?
可调用是任何可以调用的。
内置可调用(pycallable_check in objects.c)检查参数是否为:
- 类的一个实例,具有一个调用方法或
- 属于具有非空tp_调用(c struct)成员的类型,该成员以其他方式指示可调用性(如在函数、方法等中)。
名为"call"的方法是(根据文档)
Called when the instance is ''called'' as a function
例子
1 2 3 4 5 6 | class Foo: def __call__(self): print 'called' foo_instance = Foo() foo_instance() #this is calling the __call__ method |
从python的sources对象.c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /* 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; } } |
它说:
ternaryfunc tp_call An optional
pointer to a function that implements
calling the object. This should be
NULL if the object is not callable.
The signature is the same as for
PyObject_Call(). This field is
inherited by subtypes.
您可以始终使用内置的
例如,一个简单的缓存实现:
1 2 3 4 5 6 7 8 9 10 | 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 |
用途:
1 2 3 | @Cached def ack(x, y): return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1) |
标准库示例,文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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') |
可调用对象允许您使用圆括号()并最终传递一些参数,就像函数一样。
每次定义函数时,python都会创建一个可调用对象。在示例中,可以通过以下方式定义函数func(它是相同的):
1 2 3 4 5 6 7 8 9 | class a(object): def __call__(self, *args): print 'Hello' func = a() # or ... def func(*args): print 'Hello' |
您可以使用这个方法,而不是像doit或run这样的方法,我认为看到obj()比obj.doit()更清楚。
让我反向解释一下:
考虑一下……
1 | foo() |
…作为句法的糖分:
1 | foo.__call__() |
其中,
对于内置类型,在编写时:
1 2 | int('10') unicode(10) |
你基本上是在做:
1 2 | int.__call__('10') unicode.__call__(10) |
这也是为什么在python中没有
可调用对象是具有
某些排版错误会让解释器尝试调用您不希望调用的内容,例如字符串。当解释器尝试执行不可调用的应用程序时,这可能会产生错误。您可以在python解释器中通过执行下面的脚本之类的操作看到这种情况。
1 2 3 4 5 6 7 8 9 | [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 >>> |
很简单,"可调用"是可以像方法一样调用的东西。内置函数"callable()"将告诉您某个东西是否看起来是可调用的,检查call属性也是如此。函数和类一样可以调用,类实例也可以调用。在这里和这里了解更多关于这个的信息。
此示例将输出8:
1 2 3 4 5 6 7 8 9 | class Adder(object): def __init__(self, val): self.val = val def __call__(self, val): return self.val + val func = Adder(5) print func(3) |
在python中,可调用对象是类型具有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> 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 |
就这么简单:)
这当然可以超载:
1 2 3 4 5 6 7 | >>> class Foo(object): ... def __call__(self): ... return 42 ... >>> f = Foo() >>> f() 42 |
可调用是"内置函数或方法"的类型或类,具有一个方法呼叫
1 2 3 | >>> type(callable) <class 'builtin_function_or_method'> >>> |
例子:print是一个可调用的对象。具有内置函数uuu调用__当您调用print函数时,python创建一个print类型的对象,并调用它的方法,调用传递参数(如果有的话)。
1 2 3 4 5 6 7 | >>> type(print) <class 'builtin_function_or_method'> >>> print.__call__(10) 10 >>> print(10) 10 >>> |
谢谢您。当做,马里斯
检查类的函数或方法是否可调用,这意味着我们可以调用该函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 |
你可以把它放在(args)之后,期望它能工作。可调用通常是一个方法或类。方法被调用,类被实例化。
可调用对象实现