Python中的特殊方法:__call__
本文结构:
1.__call__方法
2.callable():判断对象/函数能否被调用
3.举例:斐波那契数列类
1.__call__方法
一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()
来调用。
能不能直接在实例本身上调用呢?在Python中,答案是肯定的。
任何类,只需要定义一个__call__()
方法,就可以直接对实例进行调用.
看一个例子:
class Student(object): def __init__(self,score): self.score=score def __call__(self): return self.score tim=Student(80) tim() ##result 80
__call__大大模糊了对象和函数的边界,因为对象居然也可以调用了!
2.callable():判断对象/函数能否被调用
那么如何判断一个对象或函数能否被调用呢?可以用callable()
print callable(tim) print callable(sum) print callable('ABC') ##result True True False
3.举例:斐波那契数列类
最后,用一个斐波那契数列类来实现一下直接调用对象。
下面这段代码定义了一个Fib类,通过将Fib类实例化创建了一个迭代器对象。
通过调用next方法,能够迭代打印数列的值。
class Fib(object): def __init__(self): self.a, self.b = 0, 1 # 初始化两个计数器a,b def __iter__(self): return self # 实例本身就是迭代对象,故返回自己 '''在python2中是next,在python3中是__next__''' def next(self): self.a, self.b = self.b, self.a + self.b # 计算下一个值 if self.a > 50: # 退出循环的条件 raise StopIteration() return self.a# 返回下一个值 if __name__=='__main__': test=Fib() print test.next() print test.next() print test.next() print test.next() print test.next() ##result 1 1 2 3 5
如果觉得每次都调用next方法太过麻烦,能不能直接调用实例对象?
当然可以,只需要借助一下闭包的性质即可:
class Fib(object): def __init__(self): self.a, self.b = 0, 1 # 初始化两个计数器a,b def __iter__(self): return self # 实例本身就是迭代对象,故返回自己 '''在python2中是next,在python3中是__next__''' def __call__(self): def next(self): self.a, self.b = self.b, self.a + self.b # 计算下一个值 if self.a > 50: # 退出循环的条件 raise StopIteration() return self.a# 返回下一个值 return next(self) if __name__=='__main__': test=Fib() for i in range(5): print test() ##result 1 1 2 3 5