python什么是调用_什么是Python中的"可调用"?

jfs..

79

从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;

}

}

它说:

如果一个对象是某个类的实例,那么如果它具有__call__属性,则它是可调用的.

否则该对象x可以调用iff x->ob_type->tp_call != NULL

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

您始终可以使用内置callable函数来确定给定对象是否可调用; 或者更好,但只是打电话给它,然后赶上TypeError.callable在Python 3.0和3.1中删除,使用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')

@JF塞巴斯蒂安:这是BS,更像生活的例子更好.我可以向你展示生活般的代码,让你哭泣作为一个例子.简单的例子也可以工作,它们可以更好地说明一些东西,因为它们不会分散注意力. (19认同)

我发现__call__方法的示例极具误导性,因为它将它与缓存和装饰器的配方混合在一起,这对于__call__的理解没有任何帮助. (10认同)

您正在解释什么是可调用的,但您举例说明了如何使用可调用对象来定义装饰器.我知道这是__callable__的典型用法,但这可能会让想知道什么是可调用的读者以及如何使用__callable__的读者感到困惑.我更喜欢@FlorianBösch的回答. (5认同)

JF塞巴斯蒂安,也写了更多你从其他地方复制和粘贴的例子并没有帮助. (3认同)

@Kay:我也喜欢@FlorianBösch的答案(目前的形式).顺便说一句,装饰者不是*"可调用"的典型用法.最典型的"callables"是函数/方法,例如`def f():...`,以及类对象,例如`class C:...`ie,`f`,`''..strip`,` len`和`C`都是可调用的.在类中具有`__call __()`方法的实例相对较少. (2认同)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值