首页 > 其他分享 >函数(三)——闭包函数与装饰器

函数(三)——闭包函数与装饰器

时间:2022-10-11 21:15:17浏览次数:36  
标签:闭包 index 函数 res func time print 装饰 def

一、函数名的多种用法

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

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('功能编号不存在')
    if choice == '1':
        register()
    elif choice == '2':
        login()
    elif choice == '3':
        withdraw()
    elif choice == '4':
        transfer()
    elif choice == '5':
        shopping()
    else:
        print('其他')

 

二、闭包函数

闭包函数:

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

 

 

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

给函数体代码传参的方式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()     # jason, 18
res()     # jason, 18
res = outer('kevin', 28)
res()     # kevin, 28
res()     # kevin, 28

 

三、装饰器简介

1.什么是装饰器:

装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。

2. 装饰器的原则:

    1) 不修改被装饰对象的源代码

    2) 不修改被装饰对象的调用方式

3.本质

并不是一门新的技术,而是由函数参数、名称空间、函数名多种用法、闭包函数组合到一起的结果,目的是为被装饰对象添加上新功能。

4.口诀

对修改封闭,对扩展开放

5.储备知识

时间相关操作

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():
    print('from index')
    time.sleep(3)

index()

要统计index函数执行的时间:

方案1:直接在调用index函数的前后添加代码

import time

def index():
    start = time.time()
    print('from index')
    time.sleep(1)
    end = time.time()
    print('run time is %s' %(end - start))

index()

方案2:装饰器的功能需要重复编写,代码冗余

import time

def index():
    print('from index')
    time.sleep(1)

start = time.time()
index()
end = time.time()
print('run time is %s' %(end - start))

start = time.time()
index()
end = time.time()
print('run time is %s' %(end - start))

方案3:解决方案二的代码冗余问题,但是存在问题——装饰器的功能写死了,只能装饰index函数

import time

def index():
    print('from index')
    time.sleep(1)

def wrapper():
    start = time.time()
    index()
    end = time.time()
    print('run time is %s' %(end - start))

wrapper()
wrapper()

方案4:装饰器的功能写活

import time

def index():
    print('from index')
    time.sleep(1)

def outter(func):
    # func = index
    def wrapper():
        start = time.time()
        func()
        end = time.time()
        print('run time is %s' %(end - start))
    return wrapper

index = outter(index)  #  index = wrapper的内存地址
# print(index)
index()

方案5:装饰器的功能写活

import time

def index():
    print('from index')
    time.sleep(1)


def home(name):
    print('welcome %s to home page' % name)
    time.sleep(0.5)
    return 123

def outter(func):
    # func = 最原始那个home的内存地址
    def wrapper(*args,**kwargs):
        start = time.time()
        res = func(*args,**kwargs)  # 最原始那个home的内存地址()
        end = time.time()
        print('run time is %s' % (end - start))
        return res
    return wrapper


home = outter(home)  # home = wrapper的内存地址
index = outter(index)  # home = wrapper的内存地址

res = home('egon')
print(res)

res = index()
print(res)

 

五、装饰器模板

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

 

六、装饰器语法糖

在用装饰器之前都要写上一行代码,显然是很不方便的。这时候可以用 @outer 替换代码来实现

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,函数,res,func,time,print,装饰,def
From: https://www.cnblogs.com/chen-ao666/p/16782552.html

相关文章

  • 函数剩余内容/函数装饰器
    目录今日内容概要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.装饰器简......
  • 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......