闭包函数和装饰器

闭包函数

  • 概念:在函数中(嵌套)定义另一个函数时,内部函数引用了外层函数的名字。
  • 特性
    • 闭包函数必须在函数内部定义
    • 闭包函数可引用外层函数的名字

闭包函数是函数嵌套、函数对象、名称空间与作用域结合体

闭包中被内部函数引用的变量,不会因为外部函数结束而被释放掉,而是一直存在内存中,直到内部函数被调用结束

# 闭包函数的定义
def func(y):
x = 100
def inner(): # 此处的inner 就是闭包函数
print(x)
print(y)
return inner # 闭包函数的调用
inner = func(1000)
inner()
  • 应用:为了给装饰器的使用做准备

装饰器

  • 概念:在不修改被装饰对象源代码与调用方式的前提下,添加新的功能。简单来说,就是给其他函数增加额外功能的函数

  • 装饰器必须遵循“开放封闭”原则

    • 开放:对函数功能的添加是开放的
    • 封闭:对函数功能的修改是封闭的
  • 必备条件

    • 不能改变被装饰对象源代码
    • 为被装饰对象添加新的功能
    • 不能改变被装饰对象调用方式
  • 使用装饰器,可以解决代码冗余问题,提高代码的可扩展性

  • 应用:统计时间、登录认证

说了这多理论,上代码。

需求:统计下载媒体文件的时间(简易版)

# 需求: 统计下载电影的时间。
# 一般我们实现这个功能的方式如下
import time def download_movie():
"""
下载电影功能
:return: None
"""
print("电影下载开始了……")
time.sleep(2) # 模拟电影下载2 秒
print("下载完成") start_time = time.time() # 获取当前时间戳
download_movie() # 下载电影
end_time = time.time() # 获取当前时间戳
print(f"下载时间:{end_time-start_time}")

以上代码确实实现了统计下载时间的功能,问题来了,如果我有多个类型文件下载函数,都需要统计时间呢?难道展现我们的“CV大法”?估计隔天就要被扫地出门了……

就没有什么办法可以解决了吗?当然有啦!先看代码

# 定义一个装饰器
def time_record(func):
"""
新增统计时间功能
:param func: 使用该功能的函数对象
:return: inner 函数对象
""" def inner():
# 统计开始
start_time = time.time()
func() # func() ----→ download_movie() or download_music()
end_time = time.time()
# 统计结束,打印统计时间
print(f"下载时间:{end_time-start_time}") return inner def download_movie():
"""
模拟下载电影
:return: None
"""
print("电影下载开始了……")
time.sleep(2)
print("下载完成!") def download_music():
"""
模拟下载音乐
:return: None
"""
print("歌曲下载开始了……")
time.sleep(2)
print("下载完成!") # time_record(download_movie) 返回一个inner,将其赋值给download_movie
inner = time_record(download_movie)
inner() # inner() ----→ download_movie() # time_record(download_music) 返回一个inner,将其赋值给download_music
inner1 = time_record2(download_music)
inner1()

以上代码就是对装饰器的引入,其中 time_record 就是装饰器,download_moviedownload_music 就是被装饰的函数对象。

通过观察

python基础-闭包函数和装饰器的更多相关文章

  1. Python基础之函数与装饰器

    阅读目录 一.为什么要使用函数 二.函数的定义与调用 三.函数返回值 四.函数的参数 五.本章小结 六.装饰器 一.函数流程图: 函数名的命名规则: 1.函数名必须由字母下划线数字组成,不能是关键字和 ...

  2. Python全栈开发之路 【第五篇】:Python基础之函数进阶(装饰器、生成器&迭代器)

    本节内容 一.名称空间 又名name space,就是存放名字的地方.举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方. 名称空间共3种,分别如下 ...

  3. Python之闭包函数、装饰器

    1.闭包函数 #作用域关系在函数定义阶段时就已经固定死了,与调用位置无关 # 即:在任意位置调用函数都需要跑到定义函数时寻找作用域关系 # def f1(): # x=1 # def inner(): ...

  4. 十一. Python基础(11)—补充: 作用域 & 装饰器

    十一. Python基础(11)-补充: 作用域 & 装饰器 1 ● Python的作用域补遗 在C/C++等语言中, if语句等控制结构(control structure)会产生新的作用域 ...

  5. day11 闭包函数和装饰器

    1.函数不是新知识点 主要是学习函数的用法 在面向对象编程中,一切皆对象,函数也不例外 具体的表现 1.函数可以引用 2.函数可以作为函数的参数 3.函数可以作为函数的返回值 4.可以被存储到容器类型 ...

  6. Python之函数对象、函数嵌套、名称空间与作用域、闭包函数、装饰器

    目录 一 函数对象 二 函数的嵌套 三 名称空间和作用域 四 闭合函数 五 装饰器 一.函数对象 1.函数是第一类对象 #第一类对象的特性:# 可以被引用 # 可以当做参数传递 # 返回值是函数 # ...

  7. Python入门之函数的装饰器

    本章目录: 装饰器: 一.为什么要用装饰器 二.什么是装饰器 三.无参装饰器 四.装饰器语法糖 五.认证装饰器实现 六.叠加多个装饰器 七.带参装饰器 ======================== ...

  8. python基础整理4——面向对象装饰器惰性器及高级模块

    面向对象编程 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 面向对象编程(Object Oriented Pro ...

  9. python基础知识-11-函数装饰器

    python其他知识目录 1.装饰器学习前热身准备 1.1装饰器简介 1.2装饰器热身分析 ) def func(): pass v1 = v2 = func #将函数名赋予一个变量,就和变量赋值是同 ...

随机推荐

  1. 人生,还没困难到"非死不可"

    最近半个月,美国著名的Facebook公司,出了好几件大事.第一件事,2019年9月19日,一名陈姓中国软件工程师在Facebook加州总部跳楼自杀.第二件事,2019年10月4日,一名软件工程师在座 ...

  2. wsgi相关的

    目录 web 本质 http协议 请求方式 响应状态码 请求与响应文本格式 目录 web 本质   本质就是浏览器和服务器进行通信, http协议   也叫超文本传输协议(英文:HyperText T ...

  3. jdbc 以及 事务的java类编写

    package com.gaosheng.utils; import java.sql.Connection;import java.sql.SQLException; import javax.sq ...

  4. 无人机基于Matlab/Simulink的模型开发(连载一)

    "一切可以被控制的对象,都需要被数学量化" 这是笔者从事多年研发工作得出的道理,无论是车辆控制,机器人控制,飞机控制,还是无人机控制,所有和机械运动相关的控制,如果不能被很好的数学 ...

  5. Cocos2d-x入门之旅[2]精灵

    精灵就是cocos是屏幕上移动的对象,能被我们控制,比如我们HelloWorld场景的这个图片就是精灵(Sprite) 怎么才算精灵?你能控制它的,就是一个精灵,否则就只是一个节点(Node) 准确的 ...

  6. /usr/local/lib/ruby/gems/2.4.0/gems/cocoapods-1.5.3/lib/cocoapods/command.rb:118:in `git_version': Failed to extract git version from `git --version`

    问题及分析 今天做项目的时候,执行pod update报了如下错误信息: /usr/local/lib/ruby/gems/2.4.0/gems/cocoapods-1.5.3/lib/cocoapo ...

  7. LIS&&LCS&&LCIS

    LIS #include<bits/stdc++.h> using namespace std; int n,a[100005],b[100005],ji; int main(){ cin ...

  8. 调用对象 “ha-datastoresystem”的“HostDatastoreSystem.QueryVmfsDatastoreCreateOptions” 失败。

    VMware vSphere Client上显示:在 ESXi“10.10.10.3”上调用对象 “ha-datastoresystem”的“HostDatastoreSystem.QueryVmfs ...

  9. dll劫持破坏360

    0x01 前言 说起DLL劫持技术,相信大家都不会陌生,因为这种技术的应用比较广泛,比如木马后门的启动.破解程序的内存补丁.外挂插件的注入以及加密狗的模拟等.之所以DLL劫持技术深受黑客们的喜爱,主要 ...

  10. ThinkPHP架构(一)-TP原理及路径问题及后台实现实例

    一直用CSDN的博客,由于域名当时注册写的不合适,现在想来博客园写博客,以后要坚持写啦,记录自己的技术学习路程 本人两个月前,刚完成基于PHP的研会门户网站,虽然实现了基本功能,但感觉技术有些单薄,便 ...