首页 > 编程语言 >python(闭包函数与装饰器)

python(闭包函数与装饰器)

时间:2022-10-11 23:34:19浏览次数:66  
标签:闭包 index 函数 python func time print 装饰 def

今日内容概要

  • global与nonlocal

  • 函数名的多种用法

  • 闭包函数

  • 装饰器简洁介

  • 无参装饰器

  • 装饰器模板

  • 装饰器语法糖及修复技术

global和nonlocal

money = 666

def index():
global money
money = 123

index()
print(money)

global用于局部名称空间修改全局名称空间(改变的是不可变类型)
nonlocal内层局部名称空间该外层局部名称空间

函数名的多种用法

函数名其实绑定的也是一内存地址,只不过该地址里面存放的不是数据值而是一段代码,函数加括号就会找到该代码并执行,有以下几种执行的方法:

1.可以当做变量名赋值

def index ():pass
res = index 
res()
# 把index含参数赋值给res,res就具备的有调用函数的功能

2.可以当做函数的参数

def index():
    print('form  index')
def func(a):
    print(a)
    a()
func(index)
# func函数调用index作为参数传给a,a就拥有了index的调用功能

3.可以当函数的返回值

def index():
    print('from index ')
    
def func():
    print('from func')
    return index
res = func()
print(res)
res()

image

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':lodin,
    '3':withdarw,
    '4':transfer,
    '5':shopping
}
 
    while True:
        print("""
        1.注册功能
        2.登录功能
        3.提现功能
        4.转账功能
        5.购物功能
        """)
      choice = input('请输入你要执行的编号功能:')
      if choice in func_dict:
        func_name = func_dict.(chioce)
        func_name()
    else:
        print('该功能不存在')

闭包函数

定义 在函数内部的函数,并且用到了外部函数名称空间中的名字闭包就是能够读取其他函数内部变量的函数

作用:

保存外部函数的变量,不会随着外部函数调用完而销毁

闭包的形成条件:
 1. 函数嵌套
 2. 内部函数必须使用了外部函数的变量或者参数
 3. 外部函数返回内部函数 这个使用了外部函数变量的内部函数称为闭包

1.定义在函数内容

2.用到外部函数名称空间中的名字

def index():
    name = 'jason'
    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()

装饰器的简介

概念:

# 1.不修改已有函数的源代码
# 2.不修改已有函数的调用方式
# 3.给已有函数增加额外的功能

装饰器的本质:

并不是一门新的技术,而是由函数参数、名称空间、函数多种用法、闭包函数组合到一起的结果。实质上也是一个闭包函数,也就是说,他也是一个函数嵌套。

注意与闭包函数的区别:装饰器实质上是一个闭包函数,但是装饰器这个闭包函数。他的参数有且只有一个并且是函数类型的话,他才是装饰器,否则他就是闭包函数!

口诀:

对修改封闭 对扩展开放
image

储备知识:

时间的相关操作

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)  

装饰器推导流程

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

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

start_time = time.time()
index()
end_time = time.time()
print('函数index的执行时间为>>>:', end_time-start_time)

结果:
from index
函数index的执行时间为>>>: 3.012359857559204

image

2.index调用的地方比较多,代码不可能反复拷贝:这时候就用到了一个能相同的代码在不同的位置反复执行>>>==函数==

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

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

image

3.函数体代码写死了,只能统计index的执行时间,如何才能做到统计更多的函数运行时间,直接传参变统计函数

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

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

get_time(home)

image

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

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

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()

image

5.调用的方式还是不对,使用变量名赋值绑定(*****)

import time
def index():
    time.sleep(3)
    print('from index')
def home():
    time.sleep(1)
    print('from home')
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()
结果:
from index
函数的执行时间为>>>: 3.000969648361206
from home
函数的执行时间为>>>: 1.0005121231079102

image

6.上述装饰器只能装饰无参函数 兼容性太差

import time
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')
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()#报错

image

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) # 这里再执行一遍就可以了

结果:
from func 123
函数的执行时间为>>>: 0.10327482223510742
from func1 1 2
函数的执行时间为>>>: 0.20255112648010254

image

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(

image

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

相关文章

  • 装饰器
    今日内容概要globaandnonlocal函数名的多种用法闭包函数装饰器简介无参装饰器有参装饰器装饰器模板装饰器语法糖及修复技术多层装饰器今日内容详细globaan......
  • 闭包函数与装饰器
    global与nonlocal'''global'''money=666defindex(): globalmoneymoney=100index()print(money)"""局部名称空间直接修改全局名称空......
  • 【GIS开发】osgEarth依赖库PROJ(Python)
    文章目录​​1、OSGeo/PROJ(C++)​​​​1.1编译sqlite3​​​​1.2编译libtiff​​​​1.3编译openssl​​​​1.4编译curl​​​​1.5编译PROJ9​​​​2、pyproj(pytho......
  • Python 多进程 multiprocessing 使用示例
    multiprocessing文档:​​https://docs.python.org/zh-cn/3.10/library/multiprocessing.html​​​Process、Lock、Semaphore、Queue、Pipe、Pool:​​https://cuiqingcai.......
  • 【机器学习】Python常见用法汇总
    【机器学习】Python常见用法汇总作者简介:在校大学生一枚,华为云享专家,阿里云星级博主,腾云先锋(TDP)成员,云曦智划项目总负责人,全国高等学校计算机教学与产业实践资源建设专家委......
  • 闭包函数与装饰器
    闭包函数与装饰器目录闭包函数与装饰器一、global与nonlocal二、函数名的多种用法三、闭包函数四、装饰器简介五、装饰器推导流程六、装饰器模板七、装饰器语法糖八、作业......
  • 25. 函数名的多种用法;26. 闭包函数;27. 装饰器
    25.函数名的多种用法★★★★★函数就是多了传参与返回值★★★★★函数名也是绑定的一个内存地址,只是该内存地址存放的是一段代码块。函数名(),如“fun()”,'''执行'''......
  • Python 远程部署利器 Fabric2 模块
    fabric 官网英文文档:​​http://www.fabfile.org/​​《Python自动化运维技术与最佳实践》如何用Fabric实现无密码输入提示的远程自动部署:fabric实现远程操作和部署:简介F......
  • 函数与装饰器
    函数与装饰器目录函数与装饰器global与nonlocal函数名的多种用法1、当做变量名赋值2、当作函数的参数3、当做函数的返回值4、当做容器类型闭包函数装饰器简介1、概念2、本......
  • 函数名的多种用法及装饰器
    目录global与nonlocal关键字函数名的多种使用方法闭包函数装饰器简介装饰器推导流程装饰器模板装饰语法糖global与nonlocal关键字global关键字"""局部名称空间直接修......