博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
闭包和装饰器
阅读量:4651 次
发布时间:2019-06-09

本文共 3565 字,大约阅读时间需要 11 分钟。

闭包函数

闭包如何产生的?

  因为函数内部又有嵌套函数,

  嵌套函数定义:定义在内部的函数无法在全局被调用
  所以产生了闭包问题

def func1()    def func2()        a = 1        return a    func2()

闭包产生的问题?

  就是func1 拿不到func2 的变量a

  怎么才能拿到呢?
  我们知道,函数是第一类对象(第一类对象说白了你可以把函数当成变量使用),你可以把func1中的变量(func2)通过return返回

def func1()    def func2()        a = 1        return a    return func2x = func1()    #这样就拿到了func2 并赋值给了变量xx()        # x()等同于 func2()      看明白了吧    就得到了一个返回值a   这样就拿到func2 的变量a了

而如果:

def func1(para1):    para1    def func2():        a = 1        return para1 + a    return func2func1(5)    #如果把5传给func1    就会把def func2 这个函数打包,

注意内部函数:

def func2():    a = 1    return 5 + a

func1(5)()   #等同于func2()

就变相调用函数func2() 得到返回值 6

print(func1(5)())   # 6

如果func1(8), 那么func2打包后:

def func2()        a = 1        return 8 + a

每次调用func1,就会返回(打包)一个新的闭包实例

所以:

  闭包 = 函数 + 引用环境

  闭包:python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)

装饰器

装饰器函数:

  装饰器函数本质 就是闭包的一种应用

  装饰器功能目的 就是实现 不修改原函数及其调用方式的情况下对原函数功能进行扩展

def timmer(func):     def inner():        print(1)        func()          #内部函数引用外部函数的参数变量        产生闭包函数        print(2)    return innerdef func():    print('hello')timmer(func)  #得到 inner函数名f = timmer(func)    # f = innerf()       # inner()     # 1# hello# 2

应用中涉及到的函数:

  被装饰函数

  装饰函数
  内嵌包装函数

装饰器书写格式:

def  wrapper(func):    ------------装饰函数    def inner(*args,**kwargs):   ------------内嵌包装函数        #功能添加(被装饰函数执行之前扩展的功能代码)(把这两行功能添加代码注释掉,等于去掉所有的装饰器)        ret = func(*args,**kwargs)                 #功能添加(被装饰函数执行之后扩展的功能代码)        return ret    return inner

使用:

@wrapper      #@wrapper 语法糖 等价于 func = wrapper(func) def func():    # 被装饰函数    return 1111    #带返回

装饰器 开放封闭原则:

  1.对 扩展 开放 允许代码扩展、添加新功能。(修复 bug)

  2.对 修改 封闭 修改函数,有可能牵一发动全身

 

小示例:一次登录,处处使用

flag = Truedef login(args):    def inner():        global flag        if flag:         #第一次调用函数,进入登录,要输入用户名和密码   如果第一次调用函数用户名密码正确,  flag为False,不用进入登录            username = input("Please enter your user name:")            pwd = input("Please enter your password:")            if username == 'kitty' and pwd == '123':                print("Login successfully!")                flag = False  #用户名密码正确,就把条件改变,        if not flag:          #如果flag发生变化,说明登录成功,否则,就进不去if语句,执行不了args()                args()    return inner@login                      #语法糖        def article():    print("Welcome to article!")@logindef diary():    print("Welcome to diary!")article()diary()#Please enter your user name:kitty# Please enter your password:123# Login successfully!# Welcome to article!# Welcome to diary!

使用装饰器计算代码运行时间

import timeprint(time.time())   #1970年1月1日00:00:00:000开始计秒def timer(func):    def inner():        start_time = time.time()        time.sleep(0.1)        func()        end_time = time.time()        print(end_time - start_time)    return inner@timerdef func():    print(1111)func()
View Code

取消装饰器函数:

def outer(flag):    def wrapper(func):        def inner():            if flag:                    #falg = False   就不执行扩展功能                print("扩展功能")            ret = func()            if flag:                    ##falg = False   就不执行扩展功能                print("扩展功能")            return ret        return inner    return wrapper@outer(False)#@outer(True)def func():    print('kitty')func()

多个装饰器装饰一个函数

def wrapper1(func):    def inner():        print(111)        func()        print(222)    return innerdef wrapper2(func):    def inner():        print('aaa')        func()        print('bbb')    return inner@wrapper2@wrapper1def func():    print('kitty')func()aaa# 111# kitty# 222# bbb

 

转载于:https://www.cnblogs.com/jin-yuana/p/10024639.html

你可能感兴趣的文章