python基础之函数进阶之函数作为返回值/装饰器
因为装饰器需要用到返回函数的知识,所以在这里将返回函数和装饰器合并讲解。
什么是返回函数?
我们知道,一个函数中return可以返回一个或者多个值,但其实,return不仅可以返回值,还可以返回函数。
实例:
def col(*arg):
def sum():
res_sum=0
for i in arg:
res_sum=res_sum+i
return res_sum
return sum()
a=col(1,2,3,4,5)
print(a)
#结果:15
#a=col(1,2,3,4,5) ==〉
#即a=sum,并且arg=(1,2,3,4,5)也被传入sum中了
#a()==sum()
并且因为sum()定义在col()函数中,所以sum()继承了col()函数的局部变量和参数,这就是闭包。(比如,col()的arg参数就被sum()所继承)
下面来看一个我在检验上面加红的句话时所碰到的一个问题:
#还是用上面这段代码。稍稍修改一下
def col(*arg):
res_sum=0 #注意:将这句话移动到这里了
def sum():
for i in arg:
res_sum=res_sum+i
return res_sum
return sum()
a=col(1,2,3,4,5)
print(a()) 结果报错:local variable 'res_sum' referenced before assignment
#既然内部函数可以引用外部函数的变量,为什么res_sum没有被内#部函数所引用?
为啥会报错?我当时很是疑惑,后来终于弄明白,错在这句:res_sum=res_sum+i
这句导致内部函数修改了外部函数的局部变量res_sum,这时,Python认为res_sum是内部函数的局部变量,而res_sum=res_sum+i之前并没有事先定义res_sum,所以当然会发生这种错误。
所以,需要这样进行修改:
def col(*arg):
res_sum=0
def sum():
for i in arg:
a=res_sum+i #在内部函数中定义一个新的变量a
return a
return sum
a=col(1,2,3,4,5)
print(a())
什么是装饰器?
def login():
pass
@login #关键字@
def open():
pass
上例就是一个装饰器的例子。
装饰器的作用:
当我们定义了open函数后(可以帮助我们打开某个文件),过了一段时间,发现我们需要在进行open之前进行验证用户,如何在不修改open函数的条件下将login函数和open函数进行结合,即:运行open之前先运行login? 这里就要用到装饰器。
下面我们来看一个真正的装饰器的实例:
def login(fun):
def real_login():
print('please input your password')
return fun()
return real_login
@login
def open():
print('hello world')
open()
@login相当于open=login(open) 也就是将open函数偷梁换柱了一番。
当我们运行open()时:
open=login(open)
#login(open)中的参数及局部变量:fun=open(原)
#open=login(open)的返回值!
#即:open=real_login
open()=real_login()
#因为real_login定义在login之中,所以继承其参数和局部变量
#所以整体来看open()==login(open)+real_login()+open()
实现一个可以接受任意参数的装饰器:
def outer(func):
def inner(*args,**kwargs):
print('start')
r=func(*args,**kwargs) # 这里func(*args,**kwargs)相当于f(a,b)
print('end')
return r
return inner @outer
def f(a,b):
print(a+b)
@outer
def f2(a,b,c):
print(a+b+c) f(1,2)
f2(1,2,3)
#结果:
start
3
end
start
6
end
python基础之函数进阶之函数作为返回值/装饰器的更多相关文章
- 【python基础】第19回 多层,有参装饰器 递归 二分法
本章内容概要 1. 多层装饰器 2. 有参装饰器 3. 递归函数 4. 算法(二分法) 本章内容详解 1. 多层装饰器 1.1 什么是多层装饰器 多层装饰器是从下往上依次执行,需要注意的是,被装饰的函 ...
- python函数进阶(函数参数、返回值、递归函数)
函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形 ...
- Python基础之文件处理、函数、内置函数 (三)
内置函数 一 详细见python文档,请点击 文件操作 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 文件句柄 = file('文件路径', '模式') 注:python中打开 ...
- python基础十四之匿名函数
匿名函数 处理简单问题的简化函数,关键字lambda. # 格式:函数名 = lambda 参数:返回值 anonymity = lambda s: s ** 0.5 print(anonymity( ...
- 十三. Python基础(13)--生成器进阶
十三. Python基础(13)--生成器进阶 1 ● send()方法 generator.send(value) Resumes the execution, and "sends&qu ...
- python基础篇之进阶
python基础篇之进阶 参考博客:http://www.cnblogs.com/wupeiqi/articles/5115190.html python种类 1. cpython 使用c解释器生产 ...
- python 全栈开发,Day12(函数的有用信息,带参数的装饰器,多个装饰器装饰一个函数)
函数的执行时,*打散.函数的定义时,*聚合. from functools import wraps def wrapper(f): # f = func1 @wraps(f) def inner(* ...
- 12、Python函数高级(命名空间、作用域、装饰器)
一.名称空间和作用域 1.命名空间(Namespace) 命名空间是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的. 命名空间提供了在项目中避免名字冲突的一种方法.各个命名空 ...
- python 函数结果缓存一段时间的装饰器
把函数结果缓存一段时间,比如读取一个mongodb,mongodb中的内容又在发生变化,如果从部署后,自始至终只去读一次那就感触不到变化了,如果每次调用一个函数就去读取那太频繁了耽误响应时间也加大了c ...
随机推荐
- Alpha阶段产品功能说明
先展示一下我们的功能流程图吧~ 一.学生用户 1. 学生登陆注册 BuaaClubs是北航所有在校生都可以注册登录的网站. 登陆界面是这样哒~ 2. 浏览报名活动 同学们可以在这个网站上查看所有社团发 ...
- YQCB冲刺周第四天
上图站立会议 任务看板: 今天的任务:做登录身份的验证,区别普通用户和超级管理员 遇到的困难:中文乱码问题
- 团队作业7——第二次项目冲刺(Beta版本12.09——12.10)
1.当天站立式会议照片 本次会议在5号公寓3楼召开,本次会议内容:①:熟悉每个人想做的模块.②:根据项目要求还没做的完成. 2.每个人的工作 经过会议讨论后确定了每个人的分工 组员 任务 陈福鹏 倒计 ...
- Android自定义View实现仿QQ实现运动步数效果
效果图: 1.attrs.xml中 <declare-styleable name="QQStepView"> <attr name="outerCol ...
- 『编程题全队』Alpha 阶段冲刺博客集合
『编程题全队』Alpha 阶段冲刺博客集合 »Day1 2018年4月19日 博客连接:『编程题全队』Alpha 阶段冲刺博客Day1 »Day2 2018年4月20日 博客连接:『编程题全队』Alp ...
- ORACLE LOG的管理
CREATE OR REPLACE PACKAGE PLOG IS /** * package name : PLOG *<br/> *<br/> *See : <a h ...
- JAVA 时间"dd/MMM/yyyy:HH:mm:ss Z", Locale.US
工作遇到时间格式转换问题, 就是在日志分析时, 需要将格式“15/Oct/2009:14:00:00 +0800”转为格式“2009-10-15 14:00:00”, 找了好久没有找到合适的,终于在友 ...
- js遍历数组和遍历对象
可以用for in来遍历对象,具体内容如下: <script type="text/javascript"> var objs = { ...
- Kafka日志存储原理
引言 Kafka中的Message是以topic为基本单位组织的,不同的topic之间是相互独立的.每个topic又可以分成几个不同的partition(每个topic有几个partition是在创建 ...
- BAT等公司必问的8道Java经典面试题,你都会了吗?
工作多年以及在面试中,我经常能体会到,有些面试者确实是认真努力工作,但坦白说表现出的能力水平却不足以通过面试,通常是两方面原因: 1.“知其然不知其所以然”.做了多年技术,开发了很多业务应用,但似乎并 ...