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

什么是返回函数?

我们知道,一个函数中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. 基础业务:滚动到指定位置导航固定(CSS实现)

    最近公司做的业务都是使用Vue.Element写的,涉及到的相应的基础业务像轮播.预加载.懒加载,都是使用 NPM上的工具来实现,原理和基础还是要有的,就来实现几个项目中常用到的业务. 经常见到这样的 ...

  2. 第31次Scrum会议(11/19)【欢迎来怼】

    一.小组信息 队名:欢迎来怼 小组成员 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 小组照片 二.开会信息 时间:2017/11/19 17:05~17:34,总计29min. 地 ...

  3. 20172319 《Java程序设计教程》 第10周学习总结

    20172319 2018.05.09-05.21 <Java程序设计教程>第10周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周 ...

  4. 软件项目第一次Sprint评价

    1.9-652 首先该小组在第一个冲刺阶段的目标还是很明确的,按照这个目标去完成并实现任务,最后也确实是实现了.通过展示目前已经完成了界面的设计及实现.初步的游戏人物设定.生命值设定.除了完成的这些, ...

  5. Runtime 类的使用

    package com.System.Runtime; import java.io.IOException; /* RunTime 该类类主要代表了应用程序运行的环境. getRuntime() 返 ...

  6. win10频繁提示证书即将过期怎么办

    最近几天每次开机都会提示许可证即将过期 ”Windows+R”打开“运行”窗口,输入“slmgr.vbs -xpr”并点击“确定”,弹出的窗口确实显示过期时间在本月1.29过期 百度各种激活方法后,发 ...

  7. teamcity执行jmeter脚本使用Executable with parameters方式不能正确运行解决思路

    如下图是选择command Line:Executable with parameters设置启动jmeter.bat  命令如下 command Executable: D:\apache-jmet ...

  8. Fastqc使用说明

    用FastQC检查二代测序原始数据的质量 2013-01-28 21:28:10|  分类: Bioinformatics |  标签:bioinformatics  deep-seq   |举报 | ...

  9. [转贴] IPSEC From 知乎

    作者:埃文科技链接:https://zhuanlan.zhihu.com/p/44874772来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 认识IPSec IPSec ...

  10. 微信小程序 功能函数 把数字1,2,3,4换成春,夏,秋,冬

    let season =‘1,2,3’; // console.log(season.length) if (season){ if (season.length==1){ seasonChe1=se ...