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(忽略按钮) ...
随机推荐
- 数据库--Redis
原因: 源码是官方configure过的,但官方configure时,生成的文件有时间戳信息,所以如果你的虚拟机的时间不对,比如说是2022年,就可能会出错 解决: date -s ‘yyyy-mm- ...
- js的立即执行函数
立即执行函数:常用于第三方库,好处在于隔离作用域,任何一个第三方库都会存在大量的变量和函数,为了避免变量污染(命名冲突),一般想到的方法就是使用立即执行函数.jQuery就是使用的立即执行函数. 函数 ...
- JavaScript对象(一)
Part One:对象的创建对象的创建,可以使用new Object() 或者 Object.creat(),该方法为静态函数 var foo = Object.create({x:1,y:2}); ...
- 在Deepin系统上装Python 3.8遇到的那些坑
- 作为一天时间在Deepin上都没装好Python的代表,我感觉有必要记录一下我自己的解决方法 坑1-- SSL/TLS 字样错误 "pip is configured wih locat ...
- 一个交互式可视化Python库——Bokeh
本篇为<Python数据可视化实战>第十篇文章,我们一起学习一个交互式可视化Python库--Bokeh. Bokeh基础 Bokeh是一个专门针对Web浏览器的呈现功能的交互式可视化Py ...
- 浅析js中的堆和栈
这里先说两个概念:1.堆(heap)2.栈(stack)堆 是堆内存的简称.栈 是栈内存的简称.说到堆栈,我们讲的就是内存的使用和分配了,没有寄存器的事,也没有硬盘的事.各种语言在处理堆栈的原理上都大 ...
- airtest的使用(作用类似于appium)
1.安装 下载免安装版本:http://airtest.netease.com/ 文档:http://airtest.netease.com/docs/docs_AirtestIDE-zh_CN/in ...
- 聊聊order by rand()
总结写在前面: 1. 不建议直接使用order by rand(),原因是执行代价比较大 2. 介绍了内存临时表,对于内存临时表,由于回表不需要访问磁盘,所以往往是用rowid排序,可以减少参与排序字 ...
- js运算【按位非】~ (index = ~~this.userIndex)(~~ 双破折号 如果是数字返回数字,如果不是数字 返回0)
index = ~~this.userIndex ~~ 双破折号 如果是数字返回数字,如果不是数字 返回0 这个运算符有点意思:按位非[~] 先来几个例子: ~undefined: -1 ~false ...
- 分享几个 PHP 编码的最佳实践
对于初学者而言,可能很难理解为什么某些做法更安全. 但是,以下一些技巧可能超出了 PHP 的范围. 始终使用大括号 让我们看下面的代码: if (isset($condition) && ...