1,函数参数
# *args 任意数量的位置参数
# **kwargs 任意数量的关键字参数
def any_param(first, *rest):
print(first, rest)
any_param(1, 'hello', 'world')
any_param(1, 'hello', 123)
any_param(1, ('hello', 'world'))
any_param(1, {'leon':999})
out:
1 ('hello', 'world')
1 ('hello', 123)
1 (('hello', 'world'),)
1 ({'leon': 999},)
# *和**的顺序不能反,不然会报keyword-only error
def print_args(arg, *args, **kwargs):
print('arg: ', arg)
print('*args', args)
print('**kwargs', kwargs)
print_args('Hi', 'this', 'is', 'Python', date = '2018-05-11', weather = 'sunny')
out:
arg: Hi
*args ('this', 'is', 'Python')
**kwargs {'date': '2018-05-11', 'weather': 'sunny'}
# *打头参数之后的参数只能作为关键字参数
def other_err_args(arga, *args, argb='world'):
print(args, arga, argb)
other_err_args('hello', 1, 2, 3)
def err_args(*args, arg):
print(args, arg) # keyword-only
err_args('hello', 1, 2, 3)
out:
(1, 2, 3) hello world
Traceback (most recent call last):
File "D:\WorkSpace\python\Projs\file\file.py", line 25, in <module>
err_args('hello', 1, 2, 3)
TypeError: err_args() missing 1 required keyword-only argument: 'arg'
2,函数返回多个值, 函数可以返回元组
def swap_int(x:int, y:int)->(int, int):
return(y, x)
x,y = (4, 9)
x, y = swap_int(x, y)
print(x, y)
out:
9 4
3,匿名函数
>>> swap_int = lambda x,y: (y, x)
>>> print(swap_int(8, 0))
(0, 8)
>>>
>>>
>>> # 匿名函数中绑定变量的值,lambda表达式的值是在运行时确定的
>>> # 所以要在函数定义时绑定变量
>>> x = 10
>>> a = lambda y : y*x
>>> a(2) # 此时执行时的x值为10
20
>>> x = 8
>>> a(2) # 此时执行时的x值变为8
16
>>> y = 10
>>> b = lambda z, y=y: z + y # 定义时就绑定了变量y的值
>>> b(10)
20
>>> y = 20
>>> b(10) # 函数在定义时绑定了变量,值始终不变,为10
20
>>>
4,函数鞋带额外状态
类的方式实现
# *之后的参数时关键字参数
def CbFunc(func, args, *, callback):
# *args明确以多参数传递
result = func(*args)
callback(result)
class CbHandler():
def __init__(self, name):
self.name = name
def handler(self, result):
# 格式化输出
print('[{}] Result: {}'.format(self.name, result))
cb = CbHandler('Leon')
CbFunc(lambda x, y : (x+y), (8, 9),callback = cb.handler)
out:
[Leon] Result: 17
函数闭包参考点击打开链接
函数闭包方式实现
# *之后的参数时关键字参数
def CbFunc(func, args, *, callback):
# *args明确以多参数传递
result = func(*args)
callback(result)
# 使用闭包捕获状态
def CbHandler(name):
def handler(result):
# 格式化输出
print('[{}] Result: {}'.format(name, result))
return handler
cb = CbHandler('Leon')
CbFunc(lambda x, y : (x+y), (8, 9),callback = cb)
out:
[Leon] Result: 17
使用协程
# *之后的参数时关键字参数
def CbFunc(func, args, *, callback):
# *args明确以多参数传递
result = func(*args)
callback(result)
# 使用协程的send方法作为回调
def CbHandler(name):
while True:
result = yield
# 格式化输出
print('[{}] Result: {}'.format(name, result))
cb = CbHandler('Leon')
# 启动生成器
next(cb)
CbFunc(lambda x, y : (x+y), (8, 9),callback = cb.send)
out:
[Leon] Result: 17
5,内联回调函数,通过生成器,协程,装饰器
from queue import Queue
from functools import wraps
# *之后的参数时关键字参数
def CbFunc(func, args, *, callback):
# *args明确以多参数传递
result = func(*args)
callback(result)
class FuncObj:
def __init__(self, func, args):
self.func = func
self.args = args
def InlinedFunc(func):
# 装饰器
@wraps(func)
def wrapper(*args):
f = func(*args)
# 队列保存结果
result_queue = Queue()
result_queue.put(None)
while True:
result = result_queue.get()
try:
cb = f.send(result)
CbFunc(cb.func, cb.args, callback=result_queue.put)
except StopIteration:
break
return wrapper
# test函数加上装饰器后,函数类看不到回调,隐藏到装饰器中
@InlinedFunc
def test():
f = lambda x,y:(x*y)
r = yield FuncObj(f, (2,3))
print(r)
r = yield FuncObj(f, ('hello ',2))
print(r)
test()
out:
6
hello hello