因为装饰器需要用到返回函数的知识,所以在这里将返回函数和装饰器合并讲解。

什么是返回函数?

我们知道,一个函数中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基础之函数进阶之函数作为返回值/装饰器的更多相关文章

  1. 【python基础】第19回 多层,有参装饰器 递归 二分法

    本章内容概要 1. 多层装饰器 2. 有参装饰器 3. 递归函数 4. 算法(二分法) 本章内容详解 1. 多层装饰器 1.1 什么是多层装饰器 多层装饰器是从下往上依次执行,需要注意的是,被装饰的函 ...

  2. python函数进阶(函数参数、返回值、递归函数)

    函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形 ...

  3. Python基础之文件处理、函数、内置函数 (三)

    内置函数 一 详细见python文档,请点击 文件操作 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 文件句柄 = file('文件路径', '模式') 注:python中打开 ...

  4. python基础十四之匿名函数

    匿名函数 处理简单问题的简化函数,关键字lambda. # 格式:函数名 = lambda 参数:返回值 anonymity = lambda s: s ** 0.5 print(anonymity( ...

  5. 十三. Python基础(13)--生成器进阶

    十三. Python基础(13)--生成器进阶 1 ● send()方法 generator.send(value) Resumes the execution, and "sends&qu ...

  6. python基础篇之进阶

    python基础篇之进阶 参考博客:http://www.cnblogs.com/wupeiqi/articles/5115190.html python种类 1. cpython  使用c解释器生产 ...

  7. python 全栈开发,Day12(函数的有用信息,带参数的装饰器,多个装饰器装饰一个函数)

    函数的执行时,*打散.函数的定义时,*聚合. from functools import wraps def wrapper(f): # f = func1 @wraps(f) def inner(* ...

  8. 12、Python函数高级(命名空间、作用域、装饰器)

    一.名称空间和作用域 1.命名空间(Namespace) 命名空间是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的. 命名空间提供了在项目中避免名字冲突的一种方法.各个命名空 ...

  9. python 函数结果缓存一段时间的装饰器

    把函数结果缓存一段时间,比如读取一个mongodb,mongodb中的内容又在发生变化,如果从部署后,自始至终只去读一次那就感触不到变化了,如果每次调用一个函数就去读取那太频繁了耽误响应时间也加大了c ...

随机推荐

  1. 使用sql查询mysql/oracle/sql server/gp数据库中指定表的字段信息(字段名/字段类型/字段长度/是否是主键/是否为空)

    1,根据数据库类型拼接不同URL /** * 根据类型不同拼接连接的URL * @param dbType 1:mysql.2:oracle.3:sql server.4:gp * @param ip ...

  2. 20135234mqy 实验三:敏捷开发与XP实践

    实     验    报     告 课程:Java 班级: 1352    姓名:mqy    学号:20135234 成绩:              指导教师:娄嘉鹏    实验日期:2015. ...

  3. B2

    组员1:吴晓晖(组长) 过去两天完成了哪些任务 代码重构基本完成 展示GitHub当日代码/文档签入记录 接下来的计划 推荐算法 还剩下哪些任务 组员2:陈锦谋 过去两天完成了哪些任务 重新制作图标 ...

  4. asp.net 错误24

    错误 24 “xxx.Web.xxx.xxx”不包含“xxName”的定义,并且找不到可接受类型为“xxx.Web.xxxr.xxx”的第一个参数的扩展方法“xxxName”(是否缺少 using 指 ...

  5. CANOpen学习指南

    对于初学者,相对于其他总线的资料来说,在国内CANOpen的资料并不多.而且并不是所有资料都适合初学者看的.这里给出一些建议,对CANOpen感兴趣的,可以参考一下学习的顺序. 前提:需要对CAN总线 ...

  6. Alpha阶段敏捷冲刺⑥

    1.提供当天站立式会议照片一张. 每个人的工作 (有work item 的ID),并将其记录在码云项目管理中: 昨天已完成的工作. 实现对账单条目的编辑 初步设计设置页面 今天要完成的工作. 账单明细 ...

  7. 10th 知识点学习:单元测试

    1.书中所在位置:构建之法第二章,19页—28页. 2.大致内容:书中是以案例的形式引入的介绍,具体讲述什么是单元测试,即程序员小飞进行练习单元测试,经过一系列的代码更改之后,终于成功实现.通过事后小 ...

  8. WindowsXP开机就打开数字小键盘的几种方法

    很多人WindowsXP登陆界面输入密码时,都要使用数字键盘,可是很多时候下都会出现小键盘灯不亮情况,非要每次都按一 下才行,是不是很麻烦呢?下面就把全面的解决方法告诉大家. 用户名和密码时,不要输入 ...

  9. 检测web服务器指定位置大文件是否存在

    在bugscan群里看到有人问有一个大文件,想探测其是否存在.如果使用curl的话,会将整个文件下载到节点,对于扫描没有任何用处,反而浪费了扫描时间. 于是我想到的解决办法是不使用curl,直接用底层 ...

  10. POJ2699_The Maximum Number of Strong Kings

    这题目,,,真是...诶.坑了好久. 给一个有向图.U->V表示U可以打败V并得一分. 如果一个人的得分最高,或者他打败所有比自己得分高的人,那么此人就是king. 现在给出每个人的得分,求最多 ...