Python函数名做参数,闭包,装饰器
简单讲解闭包的写法和应用,在这之前,先声明,你定义的任意一个函数都可以作为其他函数的参数。就像下面这段代码的参数func,接收的参数就是一个函数名,在函数体内部使用了func()调用执行函数。
请看下面的代码,注意标红的位置,猜猜看结果
def a(func):
def inner():
print("验证中")
func()
return inner
def f2():
print("--------2-----")
f2 = a(f2)
f2()
结果是先打印:验证中,然后打印了--------2-----,如下:
验证中
--------2------
先讲一下闭包的意思,就是像第一个函数a,有一个参数func(可以是任意参数),然后a函数体的内部又定义了一个函数,这个函数可以有参数可以没有,函数内部用到了外部函数a的参数,此时就称为闭包。这种应用场景一般是在外部的函数的参数不经常变化,但是里面的参数经常需要变的时候,比如:
def test(a,b):
def inner(x):
return a*x+b
return inner
上面这个例子,ab是两个常量,x经常变化,就可以这样调用:
c = test(2,3) #只需要调用一次,下面可以多次使用
inner(5)-------------------------à结果就是2*5+3
inner(6) -------------------------à结果就是2*6+3
……
然后我讲解一下为什么上面会出现那个的结果,讲一下程序执行的步骤:
- 先执行def a(func):这一行,是一个定义函数,不做操作
- 接着往下,执行def f1():这行,仍然不做操作
- 接着往下,执行def f2():这行,仍然不做操作
- 再往下执行一直到f2=a(f2),执行这句话的时候,先执行右侧,a(f2)即调用函数a,参数为f2,f2是一个函数名(注意哦,f2后面没有(),意思就是说这里只是把f2这个引用传递给了函数a的参数func),此时func指向了f2的函数体。进入到a函数里面,执行def inner(),这句话仍然不做操作,然后执行return inner(这里也要注意inner后面没有()),执行return这句话就是把inner返回给了等号左边的f2变量,可以理解为f2=inner
- 走f2(),这句话,第4步的时候把inner的引用给了f2,意味着f2现在指向的是inner这个函数体,也就是执行inner函数了
- Inner函数第一句打印一句话,不必说。第二句func(),还记得func指向哪里吗?注意第4步的执行右半部分的时候,把f2这个函数体的引用给了func所以此时的func()就是执行f2函数体的内容啦
上面这种情况呢,就是假如说你执行f1()、f2()等等函数的时候需要先执行一些一样的操作,本例中是print("验证中"),就可以这样用
上面说的理解了以后,那装饰器就容易理解了:
def a(func):
def inner():
print("验证中")
func()
return inner
def f1():
print("--------1-----")
@a #这句话就是使用装饰器,等同于 f2 = a(f2),装饰器也可以有多个(不要加括号)
def f2():
print("--------2-----")
#f2 = a(f2) #上面写了@a,这句话就可以省略了
f2()
如果你代码有大量重复的,就可以这样使用装饰器,把重复的代码放到a的位置,需要用到重复代码的地方用a装饰一下。
Python函数名做参数,闭包,装饰器的更多相关文章
- Python进阶(七)----带参数的装饰器,多个装饰器修饰同一个函数和递归简单案例(斐波那契数列)
Python进阶(七)----带参数的装饰器,多个装饰器修饰同一个函数和递归简单案例(斐波那契数列) 一丶带参数的装饰器 def wrapper_out(pt): def wrapper(func): ...
- 【python 】装饰器 (多个参数的函数,带参数的装饰器)【转】
最简单的模板是这样的 #-*-coding:utf-8-*- def outer(func): def inner(): print 'before' func() print 'after' # r ...
- python 装饰器 (多个参数的函数,带参数的装饰器)
最简单的模板是这样的 #-*-coding:utf-8-*- def outer(func): def inner(): print 'before' func() print 'after' # r ...
- Python函数小结(2)-- 装饰器、 lambda
本篇依然是一篇学习笔记,文章的结构首先讲装饰器,然后讲lambda表达式.装饰器内容较多,先简要介绍了装饰器语法,之后详细介绍理解和使用不带参数装饰器时应当注意到的一些细节,然后实现了一个简单的缓存装 ...
- python函数(3):装饰器
昨天学了很多函数方面的概念和知识其中有一个闭包的函数.很多人都对闭包的作用不是很清楚,今天我们就来认识一个新的知识点装饰器.它就是闭包函数的一个经典应用. 预习: 编写装饰器,为多个函数加上认证的功能 ...
- day20 Python 高阶函数,函数,嵌套,闭包 装饰器
高阶函数定义 1.函数接收的参数是一个函数名 2.函数的返回值是一个函数名 3.满足上述条件任意一个都可以称之为高阶函数 一.函数的接收参数是一个函数名 import time def foo(): ...
- Python函数篇(5)-装饰器及实例讲解
1.装饰器的概念 装饰器本质上就是一个函数,主要是为其他的函数添加附加的功能,装饰器的原则有以下两个: 装饰器不能修改被修饰函数的源代码 装饰器不能修改被修改函数的调用方式 装饰器可以简单的理 ...
- python 函数及变量作用域及装饰器decorator @详解
一.函数及变量的作用 在python程序中,函数都会创建一个新的作用域,又称为命名空间,当函数遇到变量时,Python就会到该函数的命名空间来寻找变量,因为Python一切都是对象,而在命名空间中 ...
- day12 python函数名的应用 闭包 迭代器
day12 python 一.函数名的应用(是第一类对象) 函数名的命名规范和变量是一样的 函数名其实就是变量名 def func(): print('i am funct ...
随机推荐
- .net core 3.0web_razor page项目_使用中间件接受大文件上传报错_httpRequest.Form threw an exception of type Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException_Request body too large
前言:在web项目的.net framework时文件上传时,自己常用一般处理程序接受上传文件,上传文件的大小限制是可以项目的webconfig里配置. 到core项目使用一般处理程序变成了中间件 ...
- Asp.net Core3.0 跨域配置
原文:http://www.zilaohu.cn/Jie/Detail_Jie?ID=78840a04-55b8-4988-80b2-f964fd822d63 下面配置后:被拒绝的域请求后,可以进入方 ...
- Selenium(九):Xpath选择器
1. Xpath选择器 1.1 Xpath语法简介 前面我们学习了CSS选择元素. 大家可以发现非常灵活.强大. 还有一种灵活.强大的选择元素的方式,就是使用Xpath表达式. XPath (XML ...
- golang协程同步的几种方法
目录 golang协程同步的几种方法 协程概念简要理解 为什么要做同步 协程的几种同步方法 Mutex channel WaitGroup golang协程同步的几种方法 本文简要介绍下go中协程的几 ...
- SpringBoot项目下的JUnit测试
在SpringBoot项目里,要编写单元测试用例,需要依赖4个jar.一个是最基本的JUnit,然后是spring-test和spring-boot-test. <!--test--> & ...
- mysql与oracle的语法对比
数据类型 编号 ORACLE MYSQL 注释 1 NUMBER int / DECIMAL DECIMAL就是NUMBER(10,2)这样的结构INT就是是NUMBER(10),表示整型:MYSQL ...
- 文件迁移到FileTable中
看此文档前,先参考一下文档 https://blog.csdn.net/downmoon/article/details/24374609 环境:阿里云ECS SQL Server 2017 + De ...
- kubernetes搭建(可访问外网环境部署)
版权声明:本文为博主原创文章,支持原创,转载请附上原文出处链接和本声明. 本文链接地址:https://www.cnblogs.com/wannengachao/p/11947621.html 一.前 ...
- Python通过pymysql连接数据库并进行查询和更新SQL方法封装
1.通过pymysql连接数据库并进行数据库操作2.查询数据3.更新修改SQL方法封装 import pymysql.cursors import json class OperationMysql: ...
- 关于css里决定样式优先级的权重
最近学css样式,优先级有点繁琐,简单记录一下. css中的优先级规则为: 有!important的最优先: 其次权重高的优先: 权重相同则后定义优先,会覆盖前面的. 至于权重: #id 为100: ...