可调用对象
python中有7种可调用对象:
- 用户定义的函数: 使用 def 语句或 lambda 表达式创建
- 内置函数:使用 C 语言(CPython)实现的函数,如 len 或 time.strftime
- 内置方法:使用 C 语言实现的方法,如 dict.get
- 方法:在类的定义体中定义的函数。
- 类:
- 调用类时会运行类的 __new__ 方法创建一个实例,然后运行 __init__ 方法,初始化实例,最后把实例返回给调用方。
- 因为 Python 没有 new 运算符,所以调用类相当于调用函数。(通常,调用类会创建那个类的实例,不过覆盖 __new__ 方法的话,也可能出现其他行为
- 类的实例:
- 如果类定义了 __call__ 方法,那么它的实例可以作为函数调用。
- 生成器函数:
- 使用 yield 关键字的函数或方法。
- 调用生成器函数返回的是生成器对象。
如果想判断对象能否调用,可以使用内置的 callable() 函数
>>> abs, str, 13
(<built-in function abs>, <class 'str'>, 13)
>>> [callable(obj) for obj in (abs, str, 13)]
[True, True, False]
用户定义的可调用类型
不仅 Python 函数是真正的对象,任何 Python 对象都可以表现得像函数。为此,只需实现实例方法 __call__。
import random
class BingoCage:
def __init__(self, items): #__init__ 接受任何可迭代对象;
self.__items = list(items) #在本地构建一个副本,防止列表参数的意外副作用。
random.shuffle(self.__items)
def pick(self):
try:
return self.__items.pop()
except IndexError:
raise LookupError('pick from empty BingoCage')
def __call__(self):
return self.pick()
bingo = BingoCage(range(3))
print(bingo.pick()) # 1
print(bingo()) # 0
print(callable(bingo)) # True