1、闭包的概念
closure:内部函数中对enclosing作用域的变量进行引用,外部函数返回内部函数名
 
2、函数实质与属性
函数是一个对象:在内存中有一个存储空间
函数执行完成后内部变量回收:引用计数不为零
函数属性:特殊属性
函数返回值
例子
passline = 60
def func(val):
print('%x' % id(val)) # 查看变量名地址
if val >= passline:
print('pass')
else:
print('failed')
def in_func(): # (val,)添加后是元组类型不能变的
print(val) # 引用变量后说明变量添加到内函数属性中,使用时直接在内函数中查找
in_func()
return in_func
# func(88)
a =func(88) # 将变量名指向in_func
print(a.__name__) # 查看变量名
a() #实际是调用了in_func(),相当于a和in_func指向同一个函数,a和in_func只是函数名
print(a) #查看in_func()在func函数属性中的地址
print(a.__closure__) # 查看in_func()中的属性是否存在val变量,闭包属性
3、闭包的作用和优点
  • 实现了函数封装
  • 提高代码的复用
 
4、将代码的公共部分抽出,用闭包的形式代替抽出部分,将要使用的函数当作参数
例子:
两个代码重复的方法:
def my_sum(*arg):
if len(arg) == 0: # 被除数不能为0
return 0
for val in arg: # 数据只能是int型
if not isinstance(val,int):
return 0
return sum(arg)
def my_average(*arg):
if len(arg) == 0:
return 0
for val in arg:
if not isinstance(val,int):
return 0
return sum(arg)//len(arg)
 
print(my_sum(1,2,3,'2'))
print(my_average())
重构后:
def my_sum(*arg):
return sum(arg)
def my_average(*arg):
return sum(arg)//len(arg)
def dec(func):
def in_dec(*arg):
if len(arg) == 0: # 被除数不能为0
return 0
for val in arg: # 数据只能是int型
if not isinstance(val,int):
return 0
return func(*arg)
return in_dec
my_sum = dec(my_sum) # 1、先调用dec,2、再将my_sum函数名指向函数in_dec
my_average = dec(my_average)
 
# 当使用my_sum函数时,3、调用in_dec,4、再调用my_sum
print(my_sum(1,2,3,'2'))
print(my_average())
 
5、装饰器:
 
  • 装饰器用来装饰函数
  • 返回一个函数对象
  • 被装饰函数标识符指向返回的函数对象
  • 语法:@deco
装饰器实质是对闭包的使用
def dec(func):
print('1、call dec')
def in_dec(*arg):
print('3、call in_dec')
if len(arg) == 0:
return 0
for val in arg:
if not isinstance(val,int):
return 0
return func(*arg)
print('2、return in_dec')
return in_dec
print('装饰器代码执行顺序:')
@dec # 等于my_sum = dec(my_sum)这句话
def my_sum(*arg): # 装饰过后my_sum名指向in_dec函数对象,此时in_dec会调用原来的my_sum,要使用my_sum(1,2)才能调用
print('4、call my_sum')
return sum(arg)
# print(sum(arg))
def average(*arg):
return sum(arg)//len(arg)
 
print('调用被修饰的函数后才会执行闭包中的函数')
print(my_sum(1,2,3))
输出结果:
装饰器代码执行顺序:
1、call dec
2、return in_dec
调用被修饰的函数后才会执行闭包中的函数
3、call in_dec
4、call my_sum

python基础语法_9-1闭包 装饰器补充的更多相关文章

  1. Python菜鸟之路:Python基础-逼格提升利器:装饰器Decorator

    一.装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等. 装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身 ...

  2. python 基础篇 11 函数进阶----装饰器

    11. 前⽅⾼能-装饰器初识本节主要内容:1. 函数名的运⽤, 第⼀类对象2. 闭包3. 装饰器初识 一:函数名的运用: 函数名是一个变量,但他是一个特殊变量,加上括号可以执行函数. ⼆. 闭包什么是 ...

  3. python基础编程: 函数示例、装饰器、模块、内置函数

    目录: 函数示例 装饰器 模块 内置函数 一.函数示例: 1.为什么使用函数之模块化程序设计: 不使用模块程序设计的缺点: 1.体系结构不清晰,可主读性差: 2.可扩展性差: 3.程序冗长: 2.定义 ...

  4. python基础之函数当中的装饰器

    在实际工作当中存在一个开放封闭原则 1.对扩展是开放的 为什么要对扩展开放呢? 我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代码扩展.添加新 ...

  5. Python-Day4 Python基础进阶之生成器/迭代器/装饰器/Json & pickle 数据序列化

    一.生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面 ...

  6. Python基础2:反射、装饰器、JSON,接口

    一.反射 最近接触到python的反射机制,遂记录下来已巩固.但是,笔者也是粗略的使用了__import__, getattr()函数而已.目前,笔者的理解是,反射可以使用户通过自定义输入来导入响应的 ...

  7. python基础补漏-05-生成器和装饰器

    [1]生成器 很难用简单的语言描述生成器. 生成器:从字面上来理解,就是以某种规则为基础,不断的生成数据的工具 生成器函数: 在函数中如果出现了yield关键字,那么该函数就不再是普通函数,而是生成器 ...

  8. python基础之基本算法和装饰器

    1.冒泡排序 关于冒泡排序实现大小比较,大索引会向后移动,这次循环将最大数值直接移动至最后. li = [,,,,] ): ]: temp = li[i] li[i] = li[i + ] li[i ...

  9. python基础语法7 闭包函数与装饰器

    闭包函数: 1.闭包函数必须在函数内部定义 2.闭包函数可以引用外层函数的名字 闭包函数是 函数嵌套.函数对象.名称空间与作用域 结合体. # 直接传参 def func(x): print(x) f ...

随机推荐

  1. MongoDB学习 - 安装部署

    1. docker 启动 拉取镜像 docker pull mongo:latest 指定目录启动  docker run -d -p 27017:27017 --name mongo \-v /ho ...

  2. react中create-react-app配置antd按需加载(方法二)

    1.yarn add babel-plugin-import 2.在根目录下的package.json下的bable中添加相应代码 "babel": { "presets ...

  3. 【填坑往事】使用Rxjava2的distinct操作符处理自定义数据类型去重的问题

    最近碰到一个问题,自定义数据类型列表中出现了重复数据,需要去重.处理去重的办法很多,比如借助Set集合类,使用双重循环拿每一个元素和其他元素对比等.这里介绍一种简单而且比较优雅的方式:使用Rxjava ...

  4. 小程序canvas绘制纯色圆角区域 setdata数组某一项

    小程序canvas绘制纯色圆角区域: //方法: roundRectPath:function(ctx, x, y, w, h, r) { ctx.beginPath(); ctx.moveTo(x ...

  5. 使用Kubernetes两年来的7大经验教训

    来源:分布式实验室译者:冯旭松在Ridecell公司管理基础设施团队几年后,我想在停下来休息时记录一些想法和经验教训. 1Kubernetes不仅仅是炒作 我在Kubernetes领域里活跃了很久,所 ...

  6. 无聊的周末用Java写个扫雷小游戏

    周末无聊,用Java写了一个扫雷程序,说起来,这个应该是在学校的时候,写会比较好玩,毕竟自己实现一个小游戏,还是比较好玩的.说实话,扫雷程序里面核心的东西,只有点击的时候,去触发更新数据这一步. Sw ...

  7. vue 快速入门 系列 —— 模板

    其他章节请看: vue 快速入门 系列 模板 前面提到 vue 中的虚拟 dom 主要做两件事: 提供与真实节点对应的 vNode 新旧 vNode 对比,寻找差异,然后更新视图 ①.vNode 从何 ...

  8. markdown mermaid状态图

    状态图 状态图是一种用于计算机科学和相关领域描述系统行为的图.状态图要求描述的系统由有限数量的状态组成. 语法: stateDiagram-v2 [*] --> Still Still --&g ...

  9. C++ 从&到&&

    人类发展史,就是不断挖坑.填坑的过程. 语言发展史也是如此! 任何一门设计合理的语言,给你的限制或提供的什么特性,都不是没有代价的. C的指针 指针:pointer 指针的思想起源于汇编.指针思想是编 ...

  10. 《剑指offer》面试题07. 重建二叉树

    问题描述 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍 ...