1. 主页
  2. Python基础到高级
  3. 魔术方法
  4. callable对象

callable对象

callable 对象

一个对象,只要实现了__call__方法,就可以通过小括号来调用,这一类对象,称之为可调用对象

In [1]: class Fn:
   ...:     def __call__(self):   # 在类中实现了__call__方法
   ...:         print('abc')
   ...:         

In [2]: f = Fn()   # 实例化对象

In [8]: Fn()()   # 类对象使用小括号来执行可调用对象
abc
 
In [3]: f   # 直接执行实例化,获得的结果是这个对象的描述
Out[3]: <__main__.Fn at 0x7f5d95294f60>

In [4]: f()   # 实例化加上小括号就是来调用__call__方法的
abc

确认对象是否是一个可调用对象可以使用callable方法来确认

In [5]: callable(f)   # 确认实例化对象f是否是可调用对象
Out[5]: True

In [6]: callable(Fn())   # 确认类是否是可调用对象
Out[6]: True

In [7]: callable(lambda x: x)   # 确认lambda匿名函数是否是可调用对象
Out[7]: True

callable方法的返回值都是bool类型的值

当类对象没有定义__call__方法的时候,是无法通过小括号来调用对象的

In [9]: class S:
   ...:     pass
   ...: 

In [11]: S()()   # 因为类对象S没有__call__这个方法,因此无法使用小括号来调用对象
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-1018d1bf7eb9> in <module>()
----> 1 S()()

TypeError: 'S' object is not callable

可调用对象的传参

In [12]: class Adder:
    ...:     def __call__(self,x ,y):   # 定义了一个需要传递参数的__call__方法
    ...:         return x + y
    ...:     

In [13]: Adder()(3,5)   # 当通过小括号来调用一个需要传递参数的可调用对象的时候,直接在第二组小括号里面传递指定的参数即可
Out[13]: 8

另外,在这里说明:第一组小括号是实例化对象的,第二组小括号才是调用对象的

__call__方法是为了拆分对象的逻辑

用__call__是来实现可调用对象,和闭包是殊途同归的,通常是为了封装一些内部的状态

就算不会用__call__也是没关系的,因为__call__是可以使用闭包来实现的,所以就算你不使用__call__也可以写出来高质量的代码

我们要如何帮助您?

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注