首页 > 其他分享 >闭包函数与装饰器

闭包函数与装饰器

时间:2022-10-11 22:34:13浏览次数:48  
标签:闭包 index 函数 res func time print 装饰 def

闭包函数与装饰器

目录

一、global与nonlocal

1.global:局部名称空间直接修改全局名称空间中的数据,声明局部名称空间中的变量名操作的是全局名称空间的变量名
  eg:
    x = 99
    def func():
        global x    # 声明局部变量中的x操作的是全局名称的x
        x = 22       # 将原绑定关系解开,重新绑定22
        print(x)
    func()
# 可变数据类型不需要关键字声明
  eg:
        l1 = [1,2,3,4]
        def func():
            l1 = [1,2,3]
            l1.append(999)
            print(l1)
        func()          # [1, 2, 3, 999]
2.nonlocal:内层局部名称空间修改外层局部名称中的数据
    eg:
        def func():
            x =11
            def func1():
                nonlocal x
                x =22
            func1()
            print(x)       # 22
        func()
# 可变数据类型不需要关键字声明
 eg:
     def func():
        l1 = [1,2,3,4]
        def func1():
            l1.append(888)
        func1()
        print(l1)     # [1, 2, 3, 4, 888]
    func()

二、函数名的多种用法

函数名绑定的也是一块内存地址,只不过地址里面放的不是数据值而是一段代码,函数名加括号就能找到该代码并且执行
1.可以当做变量名赋值
 eg :
      def index():
          pass
      res = index()
      res()
 # res也绑定index绑定的数据值
2.可以当做函数的参数
  eg:
     def index():
       print('from')
    def func(a):
        print(a)
        a()
    func(index)    # a形参与index实参形成动态绑定
3.可以当做函数的返回值
 eg:
     def index():
        print('from')
    def func():
        print('to')
        return index
    res = func()
    print(res)       # <function index at 0x000001EAC74961F0>
    res()
 eg:
    def index():
        print('from')
        def func():
            print('to')
        return func
    res = index()
    print(res)
    res()
4.可以当容器类型(可以存放多个数据的数据类型)的数据
  eg:
    def register():
        print('注册')
    def login():
        print('登录')
    def transfer():
        print('转账')
    def withdraw():
        print('提现')
    def shopping():
        print('购物')
func_dict = {
    '1':register,
    '2':login,
    '3':transfer,
    '4':withdraw,
    '5':shopping
}
while True:
    print('''
    1.注册
    2.登录
    3.转账
    4.提现
    5.购物
    ''')
    choice = input('请输入您的选择').strip()
    if choice in func_dict:
        func_dict.get(choice)()      # 通过键拿值
    else:
        print('功能编号不存在')
图片名称

三、闭包函数

定义在函数内部的函数,并且用到了外部函数名称空间中的名字
条件:
    1.定义在函数内部
    2.用到外部函数名称空间中的名字
简单的一个闭包函数案例:
  def index():
    name = 'jia'
    def inner():
        print(name)
闭包函数实际应用>>>:是一种给函数体代码传参的方式!!!
1.形参方式:代码里面缺什么变量名形参里面就补什么变量名
  eg:
     def register(name,age):   # 缺什么变量名补什么变量名
        print(f'''
        name:{name}
        age:{age}
        ''')
    register('jason',18)
2.闭包方式
  eg:
     def outer(name,age):
        def register():
            print(f'''
            name:{name}
            age:{age}
            ''')
        return register
    res = outer('jason',19)
    res()
    #     name:jason   age:19

四、装饰器简介

1.概念:
    在不改变被装饰对象原代码和调用方式的情况下,给被装饰对象添加新的功能
2.本质:
    并不是一门新的技术,而是由函数参数,名称空间,函数的多种用法,闭包函数组合到一起的结果
3.原则:
    对修改封闭,对拓展开放
    (不可以修改,但是可以添加新功能)
4.时间戳:
   import time
   print(time.time())  # 1665479593.2389407
  # 时间戳,1970-01-01 00:00:00所经历的秒数
 eg:
    import time
    count = 0
    start_time = time.time()
    while count < 10:
        print('你猜猜')
        count += 1
    end_time = time.time()
    print('循环消耗的时间:',end_time - start_time)

五、装饰器推导流程

推导流程:
import time
def index():
    time.sleep(0.5)
    print('from index')
def home():
    time.sleep(0.6)
    print('from home')
'''统计index函数执行的时间'''
start_time = time.time()
index()
end_time = time.time()
print('消耗的时间是:',end_time - start_time)

# index调用的地方较多,代码不可能反复拷贝,我们可以写一个函数然后相同代码可以在不同位置反复执行
def get_time():
    start_time = time.time()
    index()
    end_time = time.time()
    print('消耗的时间是:', end_time - start_time)
get_time(index)   # 在函数名调用的时候,变换函数的参数,就能统计更多的函数的运行时间

# 以上的方法虽然好,但是不符合装饰器的特征,下面的是变量名赋值绑定,适用于装饰无参函数
def outer(xxx):
    def get_time():
        start_time = time.time()
        xxx()      # 闭包函数
        end_time = time.time()
        print('消耗的时间是:',end_time - start_time)
    return get_time()
res = outer(index)
index()
res = outer(home)
home()

# 为了解决兼容性差,被装饰的函数不知道有没有参数及有几个参数的问题,做出如下整改
def func(a):
    time.sleep(0.5)
    print('from func', a)
def func1(a,b):
    time(0.6)
    print('from func1', a,b)
def func2(a,b,c):
    time.sleep(0.4)
    print('from func2', a,b,c)
def outer(xxx):
    def get_time(*args,**kwargs):
        start_time = time.time()
        xxx(*args,**kwargs)
        end_time = time.time()
        print('函数消耗的时间:',end_time - start_time)
    get_time()
func = outer(111)
func()
func1 = outer(11,22)
func1()
func2 = outer(11,22,33)
func2()

# 最后完整版,被装饰的函数有返回值
def func(a):
    time.sleep(0.1)
    print('from func', a)
    return func
def func1(a,b):
    time(0.6)
    print('from func1', a, b)
    return func1()
def outer(xxx):
    def get_time(*args,**kwargs):
        start_time = time.time()
        res = xxx(*args, **kwargs)
        end_time = time.time()
        print('函数消耗的时间:', end_time - start_time)
        return res
    return get_time
func = outer(func)
res = func(123)
print(res)

六、装饰器模板

def outer(func):
    def inner(*args,**kwargs):
        #执行被操作对象之前的操作
        res = func(*args,**kwargs)
        # 执行被操作对象之前的操作
        return res
    return inner()

七、装饰器语法糖

def outer(func):
    def inner(*args,**kwargs):
        #执行被操作对象之前的操作
        res = func(*args,**kwargs)
        # 执行被操作对象之前的操作
        return res
    return inner()
# 语法糖会自动将下面紧挨着的函数名当做第一个参数自动传给@函数调用
模板:
      def outer(func):
        def inner(*args,**kwargs):
            #执行被操作对象之前的操作
            res = func(*args,**kwargs)
            # 执行被操作对象之前的操作
            return res
        return inner()
    @outer  # func = outer(func)
    def func():
        print('哈哈哈')
        return func
    @outer  # index = outer(index)
    def index():
        print('hhhh')
        return index
    func()
    index()

八、作业

data_dict = {}
def register():
    # print('注册')
    while True:
        username = input('请输入注册的用户名').strip()
        if username in data_dict:
            print('用户名已存在')
            continue
        username = input('请输入您的用户名').strip()
        password = input('请输入您得密码').strip()
        money = input('请输入您的金额').strip()
        temp_dict = {}
        temp_dict['username'] = username
        temp_dict['password'] = password
        temp_dict['money'] = money
        data_dict[username] = temp_dict
        print(f'员工{username}注册成功')
        break

def login():
    # print('登录')
    while True:
        username = input('请输入注册的用户名').strip()
        if username not in data_dict:
            print('用户未注册,不能登录')
            continue
        password = input('请输入您的密码').strip()
        emp_data = data_dict.get(username)
        emp_name = emp_data['username']
        emp_pwd = emp_data['password']
        if emp_name == username and emp_pwd == password:
            print('登录成功')
            break
        else:
            print('用户名或者密码有误')
            break
def transfer():
    while True:
        dict_user = {'jia':123,'jason':321}
        money = 888
        emp_money = eval(input('请输入您要转账的金额'))
        if emp_money <= money:
            user = input('请输入您要转账的账户')
            if user in dict_user.keys():
                y_money = money - emp_money
                print('转账成功,您的余额为',y_money)
                break

def withdraw():
    while True:
        money = 888
        emp_money = eval(input('请输入您要提现的金额'))
        if emp_money <= money:
                y_money = money - emp_money
                print('提现成功,您的余额为',y_money)
                break

func_dict = {
    '1':register,
    '2':login,
    '3':transfer,
    '4':withdraw
}
while True:
    print('''
    1.注册
    2.登录
    3.转账
    4.提现
    ''')
    choice = input('请输入您要操作的功能编号').strip()
    if choice in func_dict:
        func_name = func_dict.get(choice)
        func_name()
    else:
        print('没有你要操作的功能编号')

标签:闭包,index,函数,res,func,time,print,装饰,def
From: https://www.cnblogs.com/zx0524/p/16782895.html

相关文章

  • 25. 函数名的多种用法;26. 闭包函数;27. 装饰器
    25.函数名的多种用法★★★★★函数就是多了传参与返回值★★★★★函数名也是绑定的一个内存地址,只是该内存地址存放的是一段代码块。函数名(),如“fun()”,'''执行'''......
  • 函数与装饰器
    函数与装饰器目录函数与装饰器global与nonlocal函数名的多种用法1、当做变量名赋值2、当作函数的参数3、当做函数的返回值4、当做容器类型闭包函数装饰器简介1、概念2、本......
  • 函数名的多种用法及装饰器
    目录global与nonlocal关键字函数名的多种使用方法闭包函数装饰器简介装饰器推导流程装饰器模板装饰语法糖global与nonlocal关键字global关键字"""局部名称空间直接修......
  • 装饰器小节
    目录global与nonlocal函数名的多种用法闭包函数装饰器简介无参装饰器有参装饰器装饰器模板装饰器语法糖及修复技术今日内容详解global与nonlocalmoney=......
  • python装饰器初级
    global与nonlocal1.global的作用:可以在局部空间里直接就该全局名称工具中的数据代码展示:name='moon'#设置了一个全局变量deffucn():name='god'#......
  • 装饰器推导
    importtimedefindex():time.sleep(3)print('fromindex')defhome():time.sleep(1)print('fromhome')'''1.直接在调用index函数的前后添加代......
  • 函数
    global与nonlocal一、global总之一句话,作用域是全局的,就是会修改这个变量对应地址的值。global语句是一个声明,它适用于整个当前代码块。这意味着列出的标识符将被解释为......
  • 闭包函数与装饰器
    昨日内容回顾函数的参数位置参数 分为位置形参和位置实参,位置形参与实参数量要一致,使用关键字传参可改变赋值顺序。默认参数 函数定义阶段赋有默认值的参数,传参时可不......
  • 函数之装饰器
    global与nonlocal1.局部名称空间直接修改全局名称空间中的数据money=123defindex():globalmoneymoney=222index()print(money)2.内层局部名称空间修......
  • 函数(三)——闭包函数与装饰器
    一、函数名的多种用法函数名其实绑定的是一块内存地址,只不过该地址里面存放的不是数据值而是一段代码,函数名加括号就会找到该代码并执行。1. 可以当做变量名赋值defi......