首页 > 其他分享 >Day 12 闭包函数 + 装饰器 (如懂*-*)

Day 12 闭包函数 + 装饰器 (如懂*-*)

时间:2024-10-25 16:47:48浏览次数:4  
标签:闭包 12 函数 res func time print Day def

目录

0 昨日复习

0.1 函数对象

0.1.1 引用

def f1():
  print(147)
f = f1

0.1.2 当作函数的返回值

def f2():
	return f1
f3 = f2()  #f1
f3()#  f1()

0.1.3 当作函数的参数

def f4(func):
  func()
f4(f1)   # f1()

0.1.4 当作容器的元素

#容器:列表,元组and so on
l = [1,2,3,l1]
l[-1]()   #f1()

0.2 函数的嵌套

from math import pi
def circle(radius,action='area'):
  if action == 'perimeter':
    def perimeter():
      return 2*pi*radius
    res = perimeter()
  else:
    def area():
      return pi*radius**2
    res = area()
  return res
res_area = circle(1)
res_perimeter = circle(1,action = 'perimeter')
print(f'area:{res_area}')
print(f'perimeter:{res_perimeter}')

0.3 空间名称与作用域

  • 内置名称空间

  • 全局名称空间

  • 局部名称空间

  • 查找顺序:内置名称空间 ---> 全局名称空间 ---> 局部名称空间

  • 执行顺序:从当前名称空间开始查找,然后逐步网上,如果当前为局部,则顺序为 局部--->全局--->内置

  • 作用域:函数内部的变量和全局的变量,可能命名相同,但不是一个东西

  • global:局部变量声明编程全局变量 (不推荐使用)

  • nonlocal:从内层函数的内部变量声明到外部变量(外层函数的内部变量)(不推荐使用)

1 闭包函数

1.1 何为闭包?

**闭包:闭是封闭(函数内部函数),包是包含(该内部函数对外部作用域而非全局作用域的变量的引用)。闭包指的是:函数内部函数对外部作用域而非全局作用域的引用。 ** (不懂先放着

1.2 代码展示(这就是闭包!)

# this be written by myself ,my understand
def f1(x): 
  def f2(y):
    res = x+y
    return res
  return f2
f3 = f1(2)
res = f3(3)
print(res)

1.3 闭包的应用

爬虫! 等学完再另外专门学爬虫

2 装饰器

2.1 装饰器是什么?

装饰的东西,工具,装饰的工具

本质也是一个函数,只不过这个函数具有装饰的功能

2.2 为什么要用装饰器?(如懂,

如果我们已经上线了一个项目,我们需要修改某一个方法,但是我们不想修改方法的使用方法,这个时候可以使用装饰器。因为软件的维护应该遵循开放封闭原则,即软件一旦上线运行后,软件的维护对修改源代码是封闭的,对扩展功能指的是开放的。

装饰器的实现必须遵循两大原则:

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

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

如懂:后面想起来了再说

2.3 怎么用装饰器?

2.3.1 改变源代码

import time
def time_count():
  print("welcome to time_count")
  start_time = time.time()
  time.sleep(3)
  end_time = time.time()
  print(f'休眠时间:{end_time - start_time}')
time_count()
time_count()

2.3.2 编写重复代码

import time
def index():
  print('welcome to index')
  time.sleep(2)
def f2():
  print('welcome to f2')
  time.sleep(2)
  
start = time.time()
index()
end = time.time()
print(f'index run time is {start - end}')

start = time.time()
f2()
end = time.time()
print(f'f2 run time is {start - end}')

2.3.3 第一种传参方式:改变调用方式

import time
def index():
  print('welcome to index')
  time.sleep(2)
  
def time_count(func):
  start = time.time()
  func()
  end = time.time()
  print(f'{func} time is {end - start}')

time_count(index)

2.3.4 第二种传参方式:报给函数(外包)

import time
def index():
  print('welcome to index')
  time.sleep(2)
  
def time_count(func):
  def wrapper():
    start = time.time()
    func()
    end = time.time()
    print(f'{func} time is {end - start}')
  return wrapper

f = time_count(index)
f()

声明:上述过程我都懂,但目前以我垃圾的认知,真不知道好用到哪了*-*

2.4 完善装饰器

如果原始的index()方法需要传参,那么我们之前的装饰器是无法实现该功能的,由于有wrapper()=index(),所以给wrapper()方法传参即可。

import time

def index():
    print('welcome to index')
    time.sleep(1)
    return 123

def home(name):
    print(f"welcome {name} to home page")
    time.sleep(1)

    return name

def time_count(func):
    # func = 最原始的index
    def wrapper(*args, **kwargs):  # 这里给wrapper 加了这俩玩意,因此能够接受任意数据的参数作为形参
        start = time.time()
        res = func(*args, **kwargs)    # 这里就要求time_count函数接收的函数必须为有参函数,即home,不能为index
        end = time.time()
        print(f"{func} time is {start-end}")

        return res  # 即此时函数wrapper(*args, **kwargs) 会得到返回值 res,即func(*args,**kwargs),
										# 即wrapper(*args, **kwargs) = func(*args,**kwargs)
    
    return wrapper # 即此时函数执行time_count(func) = wrapper = func 

home = time_count(home)  # 即home = time_count(home) = wrapper = home

res = home('egon')   # 此时home 变了,被wrapper取代了
print(f"res: {res}")

in short:这就是装饰器的常见用法。用于在不修改原始函数代码的情况下,给函数添加额外的功能。

说实话,本来就是在稀里糊涂的跟着水导的博客一个接着一个代码敲,边敲边理解,但到理解到最后有一个疑问,好像原来的home函数不在了,被取代了,但又不确实对不对,去ai了一下,果然是的被wrapper取代了,接着最后一句话瞬间明白了,有一种醍醐灌顶的感觉,^-^

image-20241025165217761

2.5 装饰器模板

def deco(func):
    def wrapper(*args,**kwargs):
        res = func(*args,**kwargs)
        return res
    return wrapper

2.6 装饰器语法糖 +

在被装饰函数正上方,并且是单独一行写上@装饰器名

userinfo_dict = {'sch':147}
is_login_list = False  #定义成可变类型或着global使其可以修改
def login(func):
    def wrapper(*args,**kwargs):
        global is_login_list
        if not is_login_list:
            username = input("请输入你的用户名>>>")
            pwd = int(input("请输入你的密码>>>"))
            if username in userinfo_dict and pwd == userinfo_dict.get(username):
                print('登陆成功')
                is_login_list = True
                res = func(*args,**kwargs)
                return res
            print("傻逼来老子这里吃霸王餐!")
        else:
            res = func(*args,**kwargs)
            return res
    return wrapper
@login
def shopping():
    print('with shopping')

def pay():
    print('with pay')

标签:闭包,12,函数,res,func,time,print,Day,def
From: https://www.cnblogs.com/chsun12/p/18502902

相关文章

  • 处理容器报错:[ERROR] .. Get “http://safeline-fvm/skynetinto“: dial tp: lookup s
    雷池社区版(WAF)是基于容器部署的在容器化应用的部署和运行过程中,我们常常会遇到各种报错信息。其中,形如“[ERROR]detect/skynet.go:114Get“http://safeline-fvm/skynetinto":dialtp:lookupsafeline-fvmon127.0.0.11:53:servermisbehaving”以及“panic:Get......
  • Spectrum 6.4G 12bit数据采集卡
    M5i.33xx-x1612位数据采集卡采样率高达6.4GS/s 产品简述高性能的M5i.33xx系列高速数据采集卡,提供了结合高精度、高采样率、高带宽和业内最快流盘速度的数字化仪指标。一个高速采集系统可以选择6.4GS/s和12bit精度的连续数据流模式至CPU或GPU。M5i系列是基于......
  • 12-linux服务器 sh自启动脚本
    screenrun.sh自启脚本#!/bin/bashecho"screenDuration_serverstart..."#killallpython3sleep0.5pushd/home/rootgpu1/interface/home/rootgpu1/miniconda3/bin/pythonscreenDuration.py&sleep1whiletruepid_array=("screenDuration.py&......
  • 120KW OBC充电机定期检测的价格和性价比如何?
    随着电动汽车的普及,充电设备的需求也在不断增加。120KWOBC充电机作为一款高效、稳定的充电设备,受到了市场的广泛关注。那么,120KWOBC充电机定期检测的价格和性价比如何呢?本文将从以下几个方面进行分析。首先,我们来了解一下120KWOBC充电机的市场价格。根据市场调查,120KWOBC充电......
  • 计算机视觉库supervision学习-day(3)-各种Annotator
    上一次学习了supervision库的Detections类,按照官方文档,接下来学习的是各种Annotator标注器类,我主要学习几个我感兴趣的、有意思的Annotator类型一、Annotator所有的XxxAnnotator类都是继承自BaseAnnotator类,并重写了其中的annotator方法(注:由于几乎大部分的XxxAnnotator类的构......
  • CAN201 In Class Test 1 Thursday Session
    CAN201InClassTest1ThursdaySession2MultiplayerNumberGuessingGame(UDPSockets)ObjectiveThisinclasstestisrequiredtousePythonforsocketprogramming.Youwillcreateamultiplayer“numberguessing”gameusingUDPsocketsprogramming,wi......
  • Swift 中如何利用闭包实现异步回调?
    在Swift中,闭包是自包含的函数代码块,可以在代码中被传递和使用。它们非常适合用于实现异步回调,主要因为闭包能够捕获和存储其所在上下文中的任何常量和变量的引用。异步回调的实现步骤如下:1、 定义一个接受闭包作为参数的函数。这个闭包的类型取决于你期望的回调数据类型和逻辑。......
  • AM05 AUT24 Outfit Of The Day Recommendation
    AM05AUT24FinalProjectAssignment:OutfitOfTheDayRecommendationSystem1AM05AUT24FinalProjectAssignment:OutfitOfTheDayRecommendationSystemIntroductionWelcometoyourfinalprojectfortheDataManagementcourse.Thisprojectisdesigned......
  • 10.12日总结
    今天上午睡觉,下午学javaJava今日总结一.数据库初步了解1.数据库,像仓库一样存储数据,同时也提供了对数据查询修改删除等功能。2.对于关系型数据库(还有非关系型数据库,很少用到)而言,会将类似的数据存储在一张表中,如雇员表。每个表也包含了各个条目,如雇员的id、名字等,每个条目叫做表......
  • 123云盘无限制下载
    国内网盘众多,大家用的比较多的网盘可能是百度网盘,但是大家苦百度网盘久矣,像我这种需要用网盘存储资料的,但是呢又不经常下载资料,如果经常需要下载和上传资料,那么开一个SVIP也无可厚非,但是偶尔下载一次开就非常的不划算了,但是百度网盘又不照顾我们这类人群。不想看文章的......