闭包与装饰器

最近学习了闭包和装饰器,简单记录一下笔记,方便以后查阅。

  1. 关于闭包
  2. 1.什么是闭包
    闭包就是一个函数
    2.如何创建闭包
    a.要有函数的嵌套(外部函数,内部函数)
    b.内部函数要使用外部函数的变量
    c.部函数必须有返回值,返回内部函数名
    3.如何使用闭包
  3. 使用闭包,完成求两个数的和:
def fnout(x):
    def fnin(y):
        #内部函数要修改外部函数的变量用nonlocal
        nonlocal x
        x+=100
        return x-y
    return fnin

print(fnout(100)(400)) 

-200

  1. 使用闭包求两点之间的距离
import math
def fnout(x1,y1):
    def fnin(x2,y2):
        return math.sqrt((x1-x2)**2+(y1-y2)**2)
    return fnin
print(fnout(1,1)(2,2)) 

1.4142135623730951

  1. 闭包的特殊用途:可以在不修改源代码的情况下,添加新的功能
    添加日志输出功能
import time
def writelog(fn):
    try:
        file=open('writelog.txt','a',encoding='utf-8')
        #向文件中写入日志信息(访问:方法名 时间:年月日)
        file.write('访问:')
        file.write(fn.__name__)
        file.write('\t')
        file.write('时间:')
        file.write(time.asctime())
        file.write('\n')
    except Exception as e:
        print(e.args)
    finally:
        file.close()
def fn1():
    print('功能1')
  • 使用闭包,不修改fn1,fn2的功能代码,添加日志信息
def fnout(fn):
    def fnin():
        writelog(fn)
        fn()
        print('使用了函数',fn.__name__)
    return fnin

fnout(fn1)()

功能1
使用了函数 fn1
(writelog文档:
访问:fn1 时间:Tue Jun 8 16:24:35 2021)

  1. 装饰器的基本使用
    在python程序中,装饰器就是一种闭包,他可以使闭包的访问方式更简单。
    使用装饰器,完成不修改fn1,fn2函数的源码,添加输出日志信息
    在python中使用装饰器,需要使用一个特殊的符号“@”来实现。在定义装饰器函数或类时,使用“@装饰器名称”的形式将符号“@”放在函数或类的定义行之前。
import time
def writelog(fn):
    try:
        file=open('writelog.txt','a',encoding='utf-8')
        file.write('访问:')
        file.write(fn.__name__)
        file.write('\t')
        file.write('时间:')
        file.write(time.asctime())
        file.write('\n')
    except Exception as e:
        print(e.args)
    finally:
        file.close()
def fnout(fn):
    def fnin():
        writelog(fn)
        fn()
        print('使用了函数',fn.__name__)
    return fnin


@fnout
def fn1():
    print('功能1')
fn1()

功能1
使用了函数 fn1
(writelog文档:
访问:fn1 时间:Tue Jun 8 16:31:05 2021)

  1. 多个装饰器的使用
    给foo函数新增功能:在调用foo函数前面,输入“I am foo”
    多个装饰器使用顺序:由近到远
def fnout(fn):
    print('装饰器1')
    def fnin():
        print("I am foo")
        fn()
    return fnin

def fnout2(fn):
    print('装饰器2')
    def fnin():
        print('hello')
        fn()
    return  fnin


@fnout2
@fnout
def foo():
    print('foo函数正在运行')

foo()

装饰器1
装饰器2
hello
I am foo
foo函数正在运行

  1. L带参数的装饰器与通用装饰器
    (**args传入元组形式的参数,**kwargs 传入字典形式的参数) 或者写
    def fnin(a,b),形参和传进来的函数形参一致)
import time
def writelog(fn):
    print('访问了方法名:',fn.__name__,'\t',time.asctime())

def fnout(fn):
    def fnin(*args):#(**kwargs 传入字典形式的参数) 或者写def fnin(a,b),形参数量和传进来的函数形参一致 ,
        writelog(fn)
        return fn(*args)
    return fnin
    
@fnout
def sum(a,b):
    return a+b

print('两数之和:',sum(10,20))

访问了方法名: sum Tue Jun 8 16:37:41 2021
两数之和: 30

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值