闭包和装饰器使用

偶尔善良 提交于 2019-12-13 23:08:04
  • 闭包
    闭包可以保存外部函数内的变量,不会随着外部函数调用完而销毁,优点是是无需重新定义,缺点需要内存无法及时释放
#下面展示了一个自定义闭包
def fun_out(a):
	def fun_inner(b):
		#a = 3 #这里定义的a与外部无关,相当于重新定义了一个变量
		#可以使用nonlocal a = 3 声明使用外部变量
		result = a + b
		print(result)
	return fun_inner
	f = fun_out(1)
	f(2)
  • 装饰器
    就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数,将外部函数传的参数改为额外的函数
# 添加一个登录验证的功能
def check(fn):
    def inner():
        print("请先登录....")
        fn()
    return inner


def comment():
    print("发表评论")

# 使用装饰器来装饰函数
comment = check(comment)
comment()

糖写法

# 添加一个登录验证的功能
def check(fn):
    print("装饰器函数执行了")
    def inner():
        print("请先登录....")
        fn()
    return inner

# 使用语法糖方式来装饰函数
@check
def comment():
    print("发表评论")
comment()

这里的@check相当于comment = check(comment)
外部函数会被调用一次,而comment的指向也发生了变化,改为了内部函数

  • 带有参数装饰器的使用
# 添加输出日志的功能
def logging(flag):

    def decorator(fn):
        def inner(num1, num2):
            if flag == "+":
                print("--正在努力加法计算--")
            elif flag == "-":
                print("--正在努力减法计算--")
            result = fn(num1, num2)
            return result
        return inner

    # 返回装饰器
    return decorator


# 使用装饰器装饰函数
@logging("+")
def add(a, b):
    result = a + b
    return result
result = add(1, 2)
print(result)

这里add(1,2)等效于logging(+)(add)(1,2)

  • 类装饰器
class Check(object):
    def __init__(self, fn):
        # 初始化操作在此完成
        self.__fn = fn

    # 实现__call__方法,表示对象是一个可调用对象,可以像调用函数一样进行调用。
    def __call__(self, *args, **kwargs):
        # 添加装饰功能
        print("请先登陆...")
        self.__fn()


@Check
def comment():
    print("发表评论")
comment()

类装饰器本质与闭包并无相同,__init__方法相当于外部函数,__call__相当于内部函数

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!