1. 函数的参数
为了能让一个函数接受任意数量的位置参数,可以使用一个* 参数;为了接受任意数量的关键字参数,使用一个以** 开头的参数;如果你还希望某个函数能同时接受任意数量的位置参数和关键字参数,可以同时使用* 和**。规则是:一个* 参数只能出现在函数定义中最后一个位置参数后面,而**参数只能出现在最后一个参数。
参数放到某个* 参数或者单个* 后面就能达到强制关键字参数效果。很多情况下,使用强制关键字参数会比使用位置参数表意更加清晰,程序也更加具有可读性。
如果需要减少某个函数的参数个数, 你可以使用functools.partial() 。partial() 函数允许你给一个或多个参数设置固定的值,减少接下来被调用时的参数个数。
2. 匿名函数
lambda 表达式允许你定义简单函数,但是它的使用是有限制的。你只能指定单个表达式,它的值就是最后的返回值。
lambda 表达式中的其他变量,是自由变量,在运行时绑定值,而不是定义时就绑定。
>>> x = 10
>>> a = lambda y: x + y
>>> x = 20
>>> b = lambda y: x + y
>>> a(10)
30
>>> b(10)
30
如果你想让某个匿名函数在定义时就捕获到值,可以将那个参数值定义成默认参数即可>>> x = 10
>>> a = lambda y, x=x: x + y
>>> x = 20
>>> b = lambda y, x=x: x + y
>>> a(10)
20
>>> b(10)
30
3. 带状态信息的回调函数实现
a. 类实现:类的属性携带状态信息,类方法作为回调函数。
b. 闭包函数实现:闭包函数取代只有一个方法的类。
c. 用协程实现:协程通过result = yield获取参数值,内部通过变量携带状态值,回调的时候使用协程的send()方法作为回调函数。
def apply_async(func, args, *, callback):
# Compute the result
result = func(*args)
# Invoke the callback with the result
callback(result)
def add(x, y)
return x+y
#类实现
class ResultHandler:
def __init__(self):
self.sequence = 0
def handler(self, result):
self.sequence += 1
print('[{}] Got: {}'.format(self.sequence, result))
>>> r = ResultHandler()
>>> apply_async(add, (2, 3), callback=r.handler)
[1] Got: 5
#闭包函数实现
def make_handler():
sequence = 0
def handler(result):
nonlocal sequence #注意这行是必须的,要修改环境变量之前
sequence += 1
print('[{}] Got: {}'.format(sequence, result))
return handler
>>> handler = make_handler()
>>> apply_async(add, (2, 3), callback=handler)
[1] Got: 5
#协程实现
def make_handler():
sequence = 0
while True:
result = yield
sequence += 1
print('[{}] Got: {}'.format(sequence, result))
>>> handler = make_handler()
>>> next(handler) # 这个是手动执行生成器之前必须初始化
>>> apply_async(add, (2, 3), callback=handler.send)
[1] Got: 5
4. 内联回调
本章涉及到装饰器、生成器配合的知识,暂时需要深入学习再探索
5. 访问闭包中定义的变量
闭包的内部变量对于外界来讲是完全隐藏的。但是,你可以通过编写访问函数并将其作为函数属性绑定到闭包上来实现这个目的。
def sample():
n = 0
# Closure function
def func():
print('n=', n)
# Accessor methods for n
def get_n():
return n
def set_n(value):
nonlocal n
n = value
# Attach as function attributes
func.get_n = get_n
func.set_n = set_n
return func