闭包和装饰器

内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(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))

 

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/wenshu/p/12257973.html