zoukankan      html  css  js  c++  java
  • 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)




  • 相关阅读:
    ExtJs系列教程
    linux 服务器时间 timedatectl命令时间时区操作详解
    aws CloudWatch Events
    AWS Shield
    aws ssm指令
    failed to set bridge addr: "cni0" already has an IP address different from 10.244.0.1/24
    AWS Systems Manager
    Amazon Inspector
    AWS 安全培训
    Amazon Inspector
  • 原文地址:https://www.cnblogs.com/Teachertao/p/13951757.html
Copyright © 2011-2022 走看看