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

函数装饰器

时间:2022-10-11 21:02:01浏览次数:39  
标签:index 函数 func time print 装饰 def

目录

内容概要

  • global 与 nonlocal
  • 函数名的多种用法
  • 闭包函数
  • 装饰器简介
  • 装饰器的推导流程
  • 装饰器的模板
  • 装饰器的语法糖

内容详解

global 与 nonlocal

1.global:若要在函数内修改全局名称空间中名字的值,当值为不可类型时,就可以使用global关键字

global关键字:
# money = 100
# def index():
#     global money # 打破局部空间 直接修改全局名称空间中的数据
#     money = 300
#
#
# index()
# print(money)

当实参的值为可变类型时,函数体内对该值的修改将直接反应到原来的值

l1 = [1, 2, 3, 4, 5]
def num_list(nums):
    nums.append(6)

num_list(l1)
print(l1)
#结果为
[1, 2, 3, 4, 5, 6]

2.nonlocal:对于嵌套多层的函数,可以使用nonlocal关键字

2.nonlocal关键字:
# def index():
#     name = 'jason'
#     def inner():
#         nonlocal name # 打破内层局部空间 直接修改外部局部空间的数据
#         name ='kevin'
#     inner()
#     print(name)
# index()

函数名的多种用法

函数名其实也是绑定的一块内存地址 只不过该地址里面存档不是数据值而是一段代码,函数名加括号就会找到该代码并执行。

1.函数名可以当做变量名赋值

def index():  # 定一个index的函数
    print('可以赋值给res吗')
res = index   # 将函数index赋值给res 
res() # res也可以调用index函数内的功能

2.函数名可以当做函数的参数

def func():  # 定一个func的函数
    print('from func') 
def index(a):  # 把func做为实参传给a 函数func和a做临时绑定
    print(a)  # 打印a查看func函数的内存地址
    a() # a可以调用func的函数内的功能
index(func)

3.函数名可以做函数的返回值

def index(): # 1.定义一个index的函数
    print('from index')
def func():  # 2.定义一个func的函数
    print('from func') 
    return index # 3.把index做为返回值,放回给func
res = func() #4.用res来接收func()的返回值 相当于把res = index
print(res) # 5.打印res来查看index的内存地址
res() #6.res()就可以调用index函数的功能

4.函数名可以当做容器类型的(可以存放多个数据的数据类型)的数据值

def regiser():
    print('注册功能')
def login():
    print('登录功能')
def withdraw():
    print('提取功能')
def transfer():
    print('转账功能')
def shopping():
    print('购物功能')
    
# 定义功能编号与功能的对应关系
func_dict = {
    '1':regiser,
    '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_dict.get(choice)
    else:
        print('该功能编号不存在')

闭包函数

1.定义:在函数内部的函数 并且用到了外部函数名称空间的名字

1.定义在函数内容
2.用到外部函数名称空间的名字

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

2.1给函数体代码传参的方式1:代码里面缺什么变量名形参,里面就补什么变量名

def register(name, age):
    print(f"""
    姓名:{name}
    年龄:{age}

""")
register('jamer', 40)

2.2给函数体代码传参的方式2:闭包函数

def outer(name, age):
    def register():
        print(f"""
        姓名:{name}
        年龄:{age}
        
        """)
    return register
res = outer('jamer',18)
res()
res()
res()
res()
res = outer('curry', 45)

装饰器简历

1.概念

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

2.本质

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

3.口诀

对修改封闭 对扩展开放

4.储备知识

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



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


装饰器推导流程

import time


def index():
    time.sleep(2)
    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('函数index的执行时间为>>>:', end_time - start_time)


get_time(index)
get_time(home
'''4.虽然实现了一定的兼容性 但是并不符合装饰器的特征 第一种传参不写 只能考虑闭包'''


def outer(xxx):
    def get_time():
        start_time = time.time()
        xxx()
        end_time = time.time()
        print('函数index的执行时间为>>>:', 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('函数index的执行时间为>>>:', end_time - start_time)

    return get_time


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 func3')


func(123)


def outer(xxx):
    def get_time(a, b):
        start_time = time.time()
        xxx()
        end_time = time.time()
        print('函数index的执行时间为>>>:', end_time - start_time)

    return get_time


# 必须要没参数传值
func2 = outer(func2)
func2()
# 必须要有一个参数传值
func = outer(func)
func(1)
# 必须要有两个参数传值
func1 = outer(func1)
func1(1, 2)
'''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):
        start_time = time.time()
        xxx(*args, **kwargs)
        end_time = time.time()
        print('函数index的执行时间为>>>:', 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('函数index的执行时间为>>>:', end_time - start_time)
        return res

    return get_time


func = outer(func)
func(123)
func1 = outer(func1)
res = func1(123, 222)
print(res)

装饰器模板

1.def outer(func):
   2. def inner(*args, **kwargs):
        5.#执行被装饰对象之前可以做的额外操作
        6.res =3.func(*args, **kwargs)
        7# 执行被装饰对象之后可以做的额外操作
       8. return res
    4.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("语法糖是给什么鬼")
    return "func"

@outer # index =outer(index)
def index():
    print("装饰器是个什么鬼")
    return "index"


func()
index()

标签:index,函数,func,time,print,装饰,def
From: https://www.cnblogs.com/zjl248/p/16782534.html

相关文章

  • 函数与装饰器
    目录global与nonlocal函数名的多种用法函数闭包装饰器简介装饰器推导流程装饰器模板装饰器语法糖作业global与nonlocal1global关键字:在函数中,如果想给全局变量赋值,则需......
  • 函数对象与闭包函数与装饰器
    目录一.global与nonlocal二.函数名的多种用法1.可以当做变量名赋值2.可以当做函数的参数3.可以当做函数的返回值4.可以当做容器类型的数据三.闭包函数四.装饰器1.装饰器简......
  • python基础之闭包函数与装饰器
    python基础之闭包函数与装饰器目录一、global与nonlocal二、函数名的多种用法1.可以当变量名2.可以当函数的参数3.可以当函数的返回值三、闭包函数1.闭包函数的实际应用四......
  • 装饰器
    1.global与nonlocal1.global:局部名称空间修改全局名称空间的数据n=100defindex():globalnn=999index()print(n)#9992.nonlocal:内层局部名......
  • C语言-函数
    1:函数的概念函数是一个命名了的代码块,我们通过调用函数执行相应的代码,函数可以有0个或者多个参数,而且会产生一个结果对于我的总结:我觉得函数可以说是一个能够实现一定功......
  • python重点之装饰器
    global与nonlocal函数名的多种用法闭包函数装饰器简介无参装饰器有参装饰器装饰器模板装饰器语法糖今日详细内容global与nonlocalmoney=666defind......
  • 函数(三)
    函数(三)global与nonlocal1.global的用法1.当不使用global时 number=89defindex(): number=34index()print(number)#89......
  • 装饰器、global与nonlocal
    目录global与nonlocal函数名的多种用法闭包函数装饰器简介装饰器推导流程装饰器模版装饰器语法糖作业global与nonlocalglobalmoney=666defindex():globalmone......
  • python进阶之路11 闭包函数 装饰器
    函数名的多种用法函数名其实绑定的也是一块内存地址只不过该地址里面存放的不是数据值而是一段代码函数名加括号就会找到该代码并执行1.可以当作变量名赋值defindex......
  • 函数名的用法,闭包函数与装饰器
    函数的多种用法与装饰器global与nonlocal1.global用在局部名称空间直接修改全局名称空间中的数据x=111deffunc():globalx#修改全局名称空间x值x=2......