Python学习笔记:函数详解(下)
本文介绍:高阶函数,嵌套函数,以及由前面两个组成的装饰器
一、高阶函数:以下两种情况都是高阶函数
1、将函数名当成参数传递给另外一个函数(作用:不修改被传递函数源代码就可以添加新功能):
import time
def a():
time.sleep(1)
print("This is A funciton...")
# b函数相当于给a函数附加了一个计算时间的功能,但未修改a的源代码
def b(func):
print(func) # 打印func的内存地址
start_time = time.time()
func() # 调用a()
end_time = time.time()
print("a函数运行时间为:%s秒" % (end_time - start_time))
b(a) # 将a函数当成一个变量传递给b
2、将函数名当成返回值返回给另外一个函数(作用:不修改被传递函数调用方式就可以添加新功能):
import time
def a1():
time.sleep(1)
print("This is A1 funciton...")
# b1函数相当于给a1函数附加了一个计算时间的功能,但未修改a的源代码,也未修改a1的调用方式
def b1(func):
start_time = time.time()
func() # 调用a()
end_time = time.time()
print("a函数运行时间为:%s秒" % (end_time - start_time))
return func
a1 = b1(a1) # 将a1函数当成一个变量传递给b1
a1() # 调用未改变a1的调用方式,依然是a1()调用,只不过此时的a1已经通过b1装饰过了。
二、嵌套函数:在函数内部定义一个新的函数,注意:函数内部根据就近原则一层层往外寻找变量
x = 0
def grandpa():
x = 1
def dad():
x = 2
def son(): x = 3
print(x)
son()
dad()
grandpa()
三、装饰器:
1、定义:在不修改函数代码和调用方式的前提下对该函数实现新功能的编程范式,形式上是利用高阶和嵌套函数的特性,高阶函数 + 嵌套函数 = 装饰器,
所以装饰器本质上是一个未其他函数添加新功能的函数,而且不破坏原有代码。
2、原则:
a、不能修改被装饰函数的代码,此项可以防止修改以后对原来的程序逻辑造成影响
b、不能修改被修饰函数的调用方式,比如原来是test()这样调用的,不能改成test(参数1)或者改名成test2()调用,这也是为了让原来的旧代码逻辑不会出现问题导致程序运行失败。
c、综上所述,也就是说被装饰的函数感觉不到装饰器的存在,装饰器是透明的。 3、如何实现装饰器?
a、函数也是一个变量,函数名是变量名,函数执行体就是具体的函数值,所以将函数名赋值给别的函数,在别的函数内部就可以直接使用该函数。
b、单层装饰器:将函数名当成变量传递给另外一个函数,以达到装饰添加新功能的目的。
def timer(func):
def deco(*args,**kwargs): #这是一个嵌套函数,将*args和**kwargs可以允许外界传入任意个数的位置和关键词参数进来
start_time = time.time()
func(*args,**kwargs)
stop_time = time.time()
print("the func run time is %s" % (stop_time - start_time)) return deco @timer #@timer标签就相当于这句话 test1 = time(test1) 将test1函数变量名传给装饰器
def test1():
time.sleep(1)
print("This is test1") @timer # test2 = time(test2)
def test2(name,age):
time.sleep(2)
print("This is %s age:%d"%(name,age)) test1()
test2("test2",23) c、通过嵌套函数两层装饰器,可以让装饰器传递参数 def outside(arg_type):
def inside(func):
def deco(*args, **kwargs):
return_value = ""
if arg_type == "1":
print("加载功能1")
return_value = func(*args, **kwargs)
print("加载功能2")
elif arg_type == "2":
print("加载功能3")
return_value = func(*args, **kwargs)
print("加载功能4")
else:
return_value = func(*args, **kwargs)
print("加载功能5")
return return_value # 这个返回值可以让被装饰的func函数的返回值传到外面
return deco
return inside @outside(arg_type="1") # 在打标签装饰的同时,还可以传递参数给外层outside
def test1():
print("This is test1")
return "test1" @outside(arg_type="2")
def test2():
print("This is test2")
return "test2" @outside(arg_type="3")
def test3(1,2):
print("This is test3")
return "test3" # test1,test2和test3的的调用方式和其内部代码都未改变,但是通过装饰器却添加了新功能
print(test1())
print(test2())
print(test3())
Python学习笔记:函数详解(下)的更多相关文章
- python基础之函数详解
Python基础之函数详解 目录 Python基础之函数详解 一.函数的定义 二.函数的调用 三.函数返回值 四.函数的参数 4.1 位置参数 4.2 关键字参数 实参:位置实参和关键字参数的混合使用 ...
- Python内置函数详解
置顶 内置函数详解 https://docs.python.org/3/library/functions.html?highlight=built#ascii https://docs.pyth ...
- python pandas字符串函数详解(转)
pandas字符串函数详解(转)——原文连接见文章末尾 在使用pandas框架的DataFrame的过程中,如果需要处理一些字符串的特性,例如判断某列是否包含一些关键字,某列的字符长度是否小于3等等 ...
- Angular6 学习笔记——组件详解之模板语法
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
- Angular6 学习笔记——路由详解
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
- Angular6 学习笔记——组件详解之组件通讯
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
- JavaScript学习笔记-实例详解-类(二)
实例详解-类(二) //===给Object.prototype添加只读\不可枚举\不可配置的属性objectId(function(){ Object.defineProperty(Object ...
- JavaScript学习笔记-实例详解-类(一)
实例详解-类(一): //每个javascript函数(除了bind())都自动拥有一个prototype对象// 在未添加属性或重写prototype对象之前,它只包含唯一一个不可枚举属性const ...
- Python学习笔记—函数
函数 我们知道圆的面积计算公式为: S = πr2 当我们知道半径r的值时,就可以根据公式计算出面积.假设我们需要计算3个不同大小的圆的面积: r1 = 12.34 r2 = 9.08 r3 = 73 ...
- Android学习笔记-Dialog详解
1.对话框的使用 1.1AlertDialog的显示 简单对话框以及监听的设置:重点掌握三个按钮(也就是三上单词): PositiveButton(确认按钮);NeutralButton(忽略按钮) ...
随机推荐
- 峰哥说技术:07-SpringBoot 正好Thymeleaf视图
Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 07 峰哥说技术:SpringBoot 正好Thymeleaf视图 Spring Boot视图介绍 虽然 ...
- Linux 文件系统及 ext2 文件系统
linux 支持的文件系统类型 Ext2: 有点像 UNIX 文件系统.有 blocks,inodes,directories 的概念. Ext3: Ext2 的加强版,添加了日志 ...
- JS的3种核心设计模式
一.单例模式 1.保证一个类仅有一个实例,并提供一个访问它的全局访问点 2.设计思路:如果存在,不创建,直接返回,不存在才创建. 在类的constructor方法里添加一个判断条件属性,并且让创建的实 ...
- 029.核心组件-Controller Manager
一 Controller Manager原理 1.1 Controller Manager概述 一般来说,智能系统和自动系统通常会通过一个"控制系统"来不断修正系统的工作状态.在K ...
- Windows通过VNC连接并显示Linux桌面(Ubuntu16.04)
目录 Linux中安装VNC服务 Linux中安装桌面环境 Windows中安装VNC Viewer Linux中安装VNC服务 sudo apt-get update sudo apt-get in ...
- .NET 5 Preview 1中的ASP.NET Core更新 (2020年3月16日)
.NET 5 Preview1现在可用,可以进行评估了! .NET 5将是当前版本. 开始 要在.NET 5.0中开始使用 ASP.NET Core,请安装.NET 5.0 SDK. 如果您使用的是W ...
- layui的弹出层的title的自定义html
layui的弹出层的title的自定义html //在这里面输入任何合法的js语句 layer.open({ type: 1 //Page层类型 ,area: ['500px', '300px' ...
- Python3学习之路~10.3 论事件驱动与异步IO
论事件驱动----详见:https://www.cnblogs.com/alex3714/articles/5248247.html Select\Poll\Epoll异步IO----详见:http: ...
- 聊聊 WebSocket,还有 HTTP
还记得曾经风靡一时的 QQ 秀聊天室吗?那时,还在上初.高中的我们,QQ 是最常用的聊天交友工具:而 QQ 秀聊天室的出现打破了只能按条件查找好友的局限性,大家可以随意进入聊天室房间,进行在线聊天.怀 ...
- 在MacOS上利用docker构建buildroot
之前有听说过docker,但是一直没有使用过.最近终于下定决定使用了一下docker,感觉docker用于跨操作系统的软件工具使用还是比较友好的. 适用人群 本文忽略的部分Linux软件包安装的过程, ...