第7章: 函数
连载中......
7.11小节
内联回调函数
>函数1
#使用异步
def apply_async(func, args, *, callback):
#Compute the result
result = func(*args)
#Invoke the callback with the result
callbace(result)
- 仔细观察,apply_async函数的参数(第二个位置和第三个位置)。
>脚本1
from queue import Queue
from functools import wraps
class Async:
def __init__(self, func, args):
self.func = func
self.args = args
def inlined_async(func):
@wraps(func)
def wrapper(*args):
f = func(*args)
result_queue = Queue()
result_queue.put(None)
while True:
result = result_queue.get()
try:
a = f.send(result) #f是一个生成器所以会有send方法,这里的send把result传到了生成器f的内部,并且推动了生成器f的运行。
apply_async(a.func, a.args, callback=result_queue.put)
except StopIteration:
break
return wrapper
def add(x, y):
return x + y
@inlined_async
def test():
r = yield Async(add, (2, 3)) #r得到了装饰器send给它的result参数
print(r)
r = yield Async(add, ('hello', 'world'))
print(r)
for n in range(10):
r = yield Async(add, (n, n))
print(r)
print('Goodbye')
#调用test
test()
#返回结果
5
helloworld
0
2
4
6
8
10
12
14
16
18
Goodbye
例子解析:
-
put()
: 在队列尾部添加一个数值 -
get()
: 在队列头部删除一个数值 -
test()
函数的执行是从它的装饰器开始的,然后在while True循环中一次一次的解开yeild,而且仔细观察可以发现,test每一个yield的对象都是Async类的实例,这说明了外层的装饰器中的a变量保存的是一个Async对象。
讨论:
- 回调函数,就是将计算挂起,然后在稍后的某个时刻计算得到了恢复,这一点非常自然的同生成器对应了起来。具体的来说就是yield会生成一个值然后就挂起,,后续调用生成器的
__next__()
或者send()
方法会使得它再次启动
7.12
访问定义在闭包内的变量
def sample():
n = 0
# Closure function
def func():
print('n=', n) #可以见到全局变量n
# Accessor methods for n
def get_n():
return n
def set_n(value):
nonlocal n
n = value
# Attach as function attributes,给闭包的函数func设置属性
func.get_n = get_n
func.set_n = set_n
return func
使用这个函数:
>>> f = sample()
>>> f()
n= 0
>>> f.set_n(10)
>>> f()
n= 10
>>> f.get_n()
10
>>>
脚本2
import sys
class ClosureInstance:
def __init__(self, locals=None):
if locals is None:
locals = sys._getframe(1).f_locals
# Update instance dictionary with callables
self.__dict__.update((key,value) for key, value in locals.items()
if callable(value) )
# Redirect special methods
def __len__(self):
return self.__dict__['__len__']()
# Example use
def Stack():
items = []
def push(item):
items.append(item)
def pop():
return items.pop()
def __len__():
return len(items)
return ClosureInstance()
例子解释:
- locals对象是字典