内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
一:. *args **kwargs
1. python函数传递参数的方式有两种:
位置参数(positional argument)
关键词参数(keyword argument)
*args 与 **kwargs 的区别,两者都是 python 中的可变参数:
*args 表示任何多个无名参数,它本质是一个 tuple(即 args是一个tuple)
**kwargs 表示关键字参数,它本质上是一个 dict(kwargs是一个dict)
如果同时使用 *args 和 **kwargs 时,必须 *args 参数列要在 **kwargs 之前。
2. 函数实参
如果函数的形参是定长参数,也可以使用 *args 和 **kwargs 调用函数,类似对元组和字典进行解引用(解包)
但是**kwargs 无法进行打印,他输出的值类似 (A="a",B="b"),但是可以作为函数的入参,fun(**kwargs)
3.序列解包
序列解包 往期博客有写过,这里只列出一个例子,序列解包没有 **。
备注: * 可以进行单独使用,也可以放在函数的实参中解包使用
** 不可以单独使用,可以放在函数的实参中解包使用;
def func(*args,**kwargs):
return args,kwargs
print(func(**{"a":1,"b":2})) # ((), {'a': 1, 'b': 2})
print(func(*[1,2,3,4])) # ((1, 2, 3, 4), {})
print(*[1,2,3,4]) # 1 2 3 4
print(**{"a":1,"b":2}) # 抛错
二: 装饰器(函数实现装饰器和类实现装饰器)
1. 不带参数
函数实现装饰器:
import functools
def log(f):
def _func(*args,**kwargs):
print("call ---",f.__name__)
return f(args,kwargs)
return _func
@log
def factorial(n):
return functools.reduce(lambda x,y: x*y, range(1, n+1))
print(factorial(10))
类实现装饰器:
import functools
class log:
def __call__(self, f):
def _func(*args, **kwargs):
print("call ---", f.__name__)
return f(*args,**kwargs)
return _func
@log()
def factorial(n):
return functools.reduce(lambda x,y: x*y, range(1, n+1))
2. 带参数得装饰器
import functools
import time
def performance(mes):
def _performance(f):
def _func(*args, **kwargs):
print(time.time())
print(f(*args, **kwargs),mes)
# return
return _func
return _performance
@performance("info")
def factorial(n):
return functools.reduce(lambda x, y: x * y, range(1, n + 1))
# factorial = performance("info")(factorial)
print(factorial(10))
通过类实现:
import functools
class log:
def __init__(self,info):
self.info = info
def __call__(self, f):
def _func(*args, **kwargs):
print("call ---", f.__name__,self.info)
return f(*args,**kwargs)
return _func
@log("info")
def factorial(n):
return functools.reduce(lambda x,y: x*y, range(1, n+1))
print(factorial(10))