首页 > 其他分享 >装饰器小节

装饰器小节

时间:2022-10-11 22:11:31浏览次数:45  
标签:index outer 小节 func time print 装饰 def

目录

  • global与nonlocal
  • 函数名的多种用法
  • 闭包函数
  • 装饰器简介
  • 无参装饰器
  • 有参装饰器
  • 装饰器模板
  • 装饰器语法糖及修复技术

今日内容详解

global与nonlocal

money = 666


def index():
    global money  # 局部修改不可变全局名称money数据值(global)
    money = 123


index()  # 调用
print(money)  # 123
'''
局部名称空间直接修改全局名称空间中的数据
'''

def index():
    name = 'gaoli'

    def inner():
        nonlocal name  # 局部名称内层修改外层局部名称空间中的数据值
        name = 'kevin'

    inner()
    print(name)


index()  # 调用  kevin
'''
内层局部名称空间修改外层局部名称空间中的数据
'''

函数名的多种用法

	函数名其实绑定的也是一块内存地址,只不过该地址里面存放的不是数据值而是一段代码,函数名加()就会找到该代码并执行。
	1.可以当作变量名赋值
    def index(): pass
    res = index
    res()  # 调用
	2.可以当作函数的参数
	 def index():
       print('from index')
	 def func(a):
       print(a)
       a()
	 func(index)
	3.可以当做函数的返回值
    def index():
        print('from index')
    def func():
        print('from func')
        return index
    res = func()
    print(res)
    res()
    
    def index():
        print('from index')
        def func():
            print('from func')
        return func
    res = index()
    print(res)
    res()
	4.可以当做容器类型(可以存放多个数据的数据类型)的数据

    def register():
        print('注册功能')

    def login():
        print('登录功能')

    def withdraw():
        print('提现功能')

    def transfer():
        print('转账功能')

    def shopping():
        print('购物功能')
    func_dict ={
        '1': register,
        '2': login,
        '3': withdraw,
        '4': transfer,
        '5': shopping
    }
    while True:
        print("""
        1.注册功能
        2.登录功能
        3.提现功能
        4.转账功能
        5.购物功能  
    """)
        choice = input('请输入功能编号>>>:').strip()  # 获取一个用户所执行的编号
        if choice in func_dict:  # 如果用户输入功能字典的编号
            func_name = func_dict.get(choice)  # 定义一个值所绑定的内存地址
            func_name()  # 调用
        else:
            print('功能编号不存在')
	5.以前写法
    while True:
        print("""
        1.注册功能
        2.登录功能
        3.提现功能
        4.转账功能
        5.购物功能  
    """)
        choice = input('请输入功能编号>>>:').strip()
        if choice == '1':
           register()
		  elif choice == '2':
			  login()
		  elif choice == '3':
			   withdraw()
		  elif choice == '4':
			   transfer()
		  elif choice == '5':
        	  shopping()
    	  else:
        	  print('可算写完了')

闭包函数

"""
定义在函数内部的函数 并且用到了外部函数名称空间中的名字
	1.定义在函数内容
	2.用到外部函数名称空间中的名字
"""
def index():
    name = 'gaoli'
    def inner():
        print(name)

闭包函数实际应用>>>:是另外一种给函数体代码传参的方式!!!

  • 给函数体代码传参的方式1:代码里面缺什么变量名形参里面就补什么变量名
def register(name,age):
	print(f"""
	姓名:{name}
	年龄:{age}
	""")
register('jason', 18) 
  • 给函数体代码传参的方式2:闭包函数
def outer(name, age):
    # name = 'jason'
    # age = 18
    def register():
        print(f"""
        姓名:{name}
        年龄:{age}
        """)
    return register
res = outer('jason', 18)
res()
res()
res = outer('kevin', 28)
res()
res()
res()

装饰器简介

  • 概念
    在不改变被装饰对象原代码和调用方式的情况下给被装饰对象添加新的功能

  • 本质
    并不是一门新的技术 而是由函数参数、名称空间、函数名多种用法、闭包函数组合到一起的结果

  • 口诀
    对修改封闭 对扩展开放

  • 储备知识

'时间相关操作'
import time
print(time.time())  # 时间戳(距离1970-01-01 00:00:00所经历的秒数)
time.sleep(3)
print('睡醒了 干饭')

count = 0
# 循环之前先获取时间戳
start_time = time.time()
while count < 100:
     print('哈哈哈')
     count += 1
end_time = time.time()
print('循环消耗的时间:', end_time - start_time)

装饰器推导流程

import time


def index():
    time.sleep(3)
    print('from index')
def home():
    time.sleep(1)
    print('from home')
'''1.直接在调用index函数的前后添加代码'''
# start_time = time.time()
# index()
# end_time = time.time()
# print('函数index的执行时间为>>>:', end_time-start_time)
'''2.index调用的地方较多 代码不可能反复拷贝>>>:相同的代码需要在不同的位置反复执行>>>:函数'''
# def get_time():
#     start_time = time.time()
#     index()
#     end_time = time.time()
#     print('函数index的执行时间为>>>:', end_time - start_time)
# get_time()
'''3.函数体代码写死了 只能统计index的执行时间 如何才能做到统计更多的函数运行时间 直接传参变换统计的函数'''
# def get_time(xxx):
#     start_time = time.time()
#     xxx()
#     end_time = time.time()
#     print('函数的执行时间为>>>:', end_time - start_time)
# get_time(index)
# get_time(home)
'''4.虽然实现了一定的兼容性 但是并不符合装饰器的特征  第一种传参不写 只能考虑闭包'''
# def outer(xxx):
#     # xxx = index
#     def get_time():
#         start_time = time.time()
#         xxx()
#         end_time = time.time()
#         print('函数的执行时间为>>>:', end_time - start_time)
#     return get_time
# res = outer(index)
# res()
# res1 = outer(home)
# res1()
'''5.调用方式还是不对 如何变形>>>:变量名赋值绑定 (******)'''
# 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)  # 赋值符号的左边是一个变量名 可以随意命名
# res1 = outer(index)
# res2 = outer(index)
# jason = outer(index)
# index = outer(index)
# index()
# home = outer(home)
# home()
'''6.上述装饰器只能装饰无参函数 兼容性太差'''
# def func(a):
#     time.sleep(0.1)
#     print('from func', a)
#
# def func1(a,b):
#     time.sleep(0.2)
#     print('from func1', a, b)
#
# def func2():
#     time.sleep(0.3)
#     print('from func2')
# func(123)
# def outer(xxx):
#     def get_time(a, b):
#         start_time = time.time()
#         xxx(a, b)
#         end_time = time.time()
#         print('函数的执行时间为>>>:', end_time - start_time)
#     return get_time
# func1 = outer(func1)
# func1(1, 2)
# func = outer(func)
# func(1)
# func2 = outer(func2)
# func2()
'''7.被装饰的函数不知道有没有参数以及有几个参数 如何兼容'''
# def func(a):
#     time.sleep(0.1)
#     print('from func', a)
# def func1(a,b):
#     time.sleep(0.2)
#     print('from func1', a, b)
# def outer(xxx):
#     def get_time(*args, **kwargs):  # get_time(1,2,3)  args=(1,2,3)
#         start_time = time.time()
#         xxx(*args, **kwargs)  # xxx(*(1,2,3))    xxx(1,2,3)
#         end_time = time.time()
#         print('函数的执行时间为>>>:', end_time - start_time)
#     return get_time
# func = outer(func)
# func(123)
# func1 = outer(func1)
# func1(1, 2)
'''8.如果被装饰的函数有返回值'''
def func(a):
    time.sleep(0.1)
    print('from func', a)
    return 'func'
def func1(a,b):
    time.sleep(0.2)
    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)

func1 = outer(func1)


res = func1(123, 123)
print(res)

装饰器模板

# 务必掌握
def outer(func):
    def inner(*args, **kwargs):
        # 执行被装饰对象之前可以做的额外操作
        res = func(*args, **kwargs)
        # 执行被装饰对象之后可以做的额外操作
        return res
    return inner

装饰器语法糖

def outer(func_name):
    def inner(*args, **kwargs):
        print('执行被装饰对象之前可以做的额外操作')
        res = func_name(*args, **kwargs)
        print('执行被装饰对象之后可以做的额外操作')
        return res
    return inner
"""
语法糖会自动将下面紧挨着的函数名当做第一个参数自动传给@函数调用
"""
@outer  # func = outer(func)
def func():
    print('from func')
    return 'func'

@outer  # index = outer(index)
def index():
    print('from index')
    return 'index'

func()
index()

标签:index,outer,小节,func,time,print,装饰,def
From: https://www.cnblogs.com/gaoli111/p/16780169.html

相关文章

  • python装饰器初级
    global与nonlocal1.global的作用:可以在局部空间里直接就该全局名称工具中的数据代码展示:name='moon'#设置了一个全局变量deffucn():name='god'#......
  • 装饰器推导
    importtimedefindex():time.sleep(3)print('fromindex')defhome():time.sleep(1)print('fromhome')'''1.直接在调用index函数的前后添加代......
  • 闭包函数与装饰器
    昨日内容回顾函数的参数位置参数 分为位置形参和位置实参,位置形参与实参数量要一致,使用关键字传参可改变赋值顺序。默认参数 函数定义阶段赋有默认值的参数,传参时可不......
  • 函数之装饰器
    global与nonlocal1.局部名称空间直接修改全局名称空间中的数据money=123defindex():globalmoneymoney=222index()print(money)2.内层局部名称空间修......
  • 函数(三)——闭包函数与装饰器
    一、函数名的多种用法函数名其实绑定的是一块内存地址,只不过该地址里面存放的不是数据值而是一段代码,函数名加括号就会找到该代码并执行。1. 可以当做变量名赋值defi......
  • 函数剩余内容/函数装饰器
    目录今日内容概要1.global与nonlocal用法2.函数名的多种用法3.闭包函数4.装饰器介绍5.装饰器原理推导过程6.装饰器模板7.装饰器语法糖练习题及答案今日内容概要global和......
  • 闭包函数与装饰器
    今日内容总结global与nonlocalmoney=666defindex():globalmoneymoney=123index()print(money)"""局部名称空间直接修改全局空间中的数据"""......
  • 函数装饰器
    目录内容概要内容详解global与nonlocal函数名的多种用法闭包函数装饰器简历装饰器推导流程装饰器模板装饰器语法糖内容概要global与nonlocal函数名的多种用法闭包......
  • 函数与装饰器
    目录global与nonlocal函数名的多种用法函数闭包装饰器简介装饰器推导流程装饰器模板装饰器语法糖作业global与nonlocal1global关键字:在函数中,如果想给全局变量赋值,则需......
  • 函数对象与闭包函数与装饰器
    目录一.global与nonlocal二.函数名的多种用法1.可以当做变量名赋值2.可以当做函数的参数3.可以当做函数的返回值4.可以当做容器类型的数据三.闭包函数四.装饰器1.装饰器简......