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

什么是返回函数?

我们知道,一个函数中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. 大华摄像头WEB页面集成

    对于海康.大华的摄像头web页面内的集成方式,根据浏览器类型,通常是采用以下形式: IE内核:调用ocx控件 例如: <object width="100%" height= ...

  2. 实验三 敏捷开发与XP实践 实验报告 20135232王玥

    一.实验内容 1. XP基础 2. XP核心实践 3. 相关工具 二.实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程 2. ...

  3. Code128

    条形码 条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符.常见的条形码是由反射率相差很大的黑条(简称条)和白条(简称空)排成的平行线图案.条形 ...

  4. c++ imooc自学计划

    一.视频学习相关的课程列表: C++远征之起航篇http://www.imooc.com/learn/342: C++远征之离港篇http://www.imooc.com/learn/381: C++ ...

  5. HDU 1565 方格取数(1) 轮廓线dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others) ...

  6. POJ 1239 Increasing Sequences 动态规划

    题目链接: http://poj.org/problem?id=1239 Increasing Sequences Time Limit: 1000MSMemory Limit: 10000K 问题描 ...

  7. java拓荒者

    因为是初学者 最近在看那个<java从入门到精通 韩顺平>的视频 觉得好不错 虽然视频的分辨率强差人意 但仍可接受 学知识嘛 用我们广东话说 :“鬼叫你穷,顶硬上” 韩老师的声音较好 课堂 ...

  8. JS获取地址栏中的链接URL参数

    function getUrlParam(name){ var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&am ...

  9. 佣金维护测试sql

    SELECT bmc.memberid , case then decode(bmc.source, , , 'TOPfitIBL') ELSE decode(bmc.source, , , 'TOP ...

  10. 关于Jquery使用中遇到典型问题集锦

    ①$.post("url",{search:1},function(){},"json")请求数据成功就是不执行回调函数? 答:最大可能导致原因为 数据格式不正 ...