Python基础之函数的闭包与装饰器的介绍

1、闭包的概念:

如果在一个函数中,定义了另外一个函数,并且那个函数使用了外面函数的变量,并且外面那个函数返回了里面这个函数的引用,那么称为里面的这个函数为闭包。

2、话不多说,以demo示例:

def Gen(x):
def fun(y):
return x+y
return fun
G = Gen(5) == 等同于 Gen(x)(y)
print(G(5))
其中 fun函数就是闭包的意思

3、闭包实现简单的计算器实战

闭包操作简单计算器

def calculator(option):
operator = None
if option == 1:
def add(x,y):
return x+y
operator = add
elif option == 2:
def minus(x,y):
return x-y
operator = minus
elif option == 3:
def multiply(x,y):
return x*y
operator = multiply
elif option == 4:
def divide(x,y):
return x/y
operator = divide
else:
print('输入有误!')
return operator

cal = calculator(3)
ret = cal(2,2)
print(ret)

4、nonlocal关键字概念

如果想要在闭包中修改外面函数的变量,这时候应该使用nonlocal关键字,来把这个变量标识为外面函数的变量:
def greet(name):
def say_hello():
nonlocal name
name += 'hello'
print('hello my name is %s' % name)
return say_hello
greet('Auawei')()

5、装饰器概念:

# 装饰器利用了函数也可以作为参数传递和闭包的特性,可以让我们的函数在执行之前或者执行之后方便的添加一些代码。
# 这样就可以做很多事情了,比如@classmethod装饰器可以将一个普通的方法设置为类方法,@staticmethod装饰器可以将一个普通的方法设置为静态方法等。
# 所以明白了装饰器的原理以后,我们就可以自定义装饰器,从而实现我们自己的需求
is_user = {
'username':True
}

def case():
def login_pw(func):
def wapper():
if is_user['username'] == True:
func()
else:
print('跳转到登录界面')
return wapper

@login_pw
def edit_user():
print('编辑用户成功')

@login_pw
def add_attr():
print('新增属性成功')

# edit_user() ==login_pw(edit_user)()
edit_user()
add_attr()
case()

其中在edit_user函数上加上@login_pw表示函数装饰器,edit_user() 等同于 login_pw(func)()
实际上就是 login_pw(edit_user)在运行wapper函数,判断成功后再次运行edit_user()函数。
# 被装饰的函数带有参数该如何解决

is_user = {
'username':True
}

def case():
def login_pw(func):
# *args 位置参数 **kwargs 关键字参数 两者组合再一起是万能参数
def wapper(*args,**kwargs):
if is_user['username'] == True:
func(*args,**kwargs)
else:
print('跳转到登录界面')
return wapper

@login_pw
def edit_user(username):
print('编辑用户成功:%s'%username)

@login_pw
def add_attr(title,context):
print('新增属性成功,标题: %s,内容: %s'%(title,context))

# edit_user() ==login_pw(edit_user)()
edit_user('Teacher')
add_attr('博客园','更新博客')
case()

# 带参数的装饰器:
# 装饰器也可以传递参数。

def login_required(site='front'):
def outter_wapper(func):
def innter_wapper(*args,**kwargs):
if site == 'front':
if is_user['username'] == True:
print('进入前台界面')
func(*args,**kwargs)
else:
print('返回登录前台首页')
else:
if is_user['username'] == True:
print('进入后台界面')
func(*args,**kwargs)
else:
print('返回登录后台首页')
return innter_wapper
return outter_wapper

@login_required()
def edit_user(username):
print('编辑用户成功:%s' % username)

@login_required("flase")
def add_attr(title,context):
print('新增属性成功,标题: %s,内容: %s'%(title,context))

edit_user('KTModel1111')
add_attr('Title','Teather')
# wraps装饰器:
from functools import wraps

def login_required(func):
@wraps(func)
def wrapper1(*args,**kwargs):
if is_user['username'] == True:
func(*args,**kwargs)
else:
print('跳转到登录页面')
return wrapper1

@login_required
def edit_user1(username):
print('用户名修改成功:%s'%username)

edit_user1('Key')
print(edit_user1.__name__)

# 实战:实现一个可以计算一个函数用时多久的装饰器

from time import time
from functools import wraps

def cal(func):
@wraps(func)
def wrapper(*args,**kwargs):
start = time()
func(*args,**kwargs)
end = time()
ctime = end - start
print('函数计算时间间隔为%f'%ctime)
return wrapper

@cal
def Add(x,y):
print(x*y)

Add(6,4)




原文地址:https://www.cnblogs.com/Teachertao/p/13951757.html