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(忽略按钮) ...
随机推荐
- python3 flask shell
python shell来操作flask flask shell 报错: from flask_bootstrap import BootstrapImportError: No module nam ...
- Feign 注解翻译器 三
一.自定义注解翻译器 (1)JAXRS 注解翻译器实例 ① 导入JAXRS所需要的jar包 <dependency> <groupId>io.github.openfeign& ...
- Docker深入浅出系列 | 5分钟搭建你的私有镜像仓库
Docker已经上市很多年,不是什么新鲜事物了,很多企业或者开发同学以前也不多不少有所接触,但是有实操经验的人不多,本系列教程主要偏重实战,尽量讲干货,会根据本人理解去做阐述,具体官方概念可以查阅官方 ...
- js 小练习题
<script> /*1.结论,IIFE中运行顺序3,1,执行test(4),会传递参数*/ /*var a=5; var test = (function(a){ console.log ...
- linux 执行计划任务crontab
crontab 一些常用的命令 service crond start //启动服务 service crond stop //关闭服务 service crond restart //重启服务 se ...
- File判断功能(新手)
//导入的一个类.import java.io.File;/* File判断功能*///创建的一个类.public class zylx3 { //公共静态的主方法. public static vo ...
- 三万字、91道MySQL面试题。 附PDF
文末领取面试题 高清PDF 数据库基础知识 1. 为什么要使用数据库 数据保存在内存 优点:存取速度快 缺点:数据不能永久保存 数据保存在文件 优点:数据永久保存 缺点:1)速度比内存操作慢,频繁的I ...
- Apex_2. LiveBos两个时间求相差天数、历时
(1)获取两个时间相差天数(没有上午下午区分) var d1=ABS_DATESTRING(FStartTime,'yyyy/MM/dd'); var d2=ABS_DATESTRING(FEndTi ...
- JVM收集器简介
JVM GC收集器集合:
- 阿里云服务器安装Docker
在阿里云服务器上安装Docker,服务器的系统是CentOS 7.6, 所以可以看官方Docker安装文档:https://docs.docker.com/install/linux/docker-c ...