#统计函数运行时间
import time
#装饰器
def timmer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
func()
stop_time =time.time()
print("the func time is %s"%(stop_time-start_time)) #函数
@timmer
def test1():
time.sleep(3)
print('in the test1') test1()

上面函数运行会出现报错:

函数调用时出错;
'NoneType' object is not callable
此时将调用函数语句去掉后面的括号,改为 test1即可。
装饰器:本质是函数(装饰其他函数)就是为其他函数添加附加功能 
高阶函数+嵌套函数==》装饰器
原则:不能修改被装饰函数的原代码
         不能修改被装饰函数的调用方式
实现装饰器:
1.函数即‘’变量‘’
2.高阶函数: 满足两个条件之一
a:把一个函数名当做实参传给另外一个函数(在不修改被装饰函数的源代码的情况下,为其添加功能)。
b:返回值中包含函数名。(不修改函数的调用方式)
实现高阶函数a

 import time
def bar():
time.sleep(3)
print('in the bar')
#装饰器,
def test1(func):
print(func)
start_time=time.time()
func() #run bar
stop_time = time.time()
print('the func runtime is %s'%(stop_time-start_time)) test1(bar) #改变了函数原本的调用方式
 #装饰器中,使用函数作为变量,通过变量也能调用该函数。

 func=bar()

 func()

 #此处和bar()的执行结果是一样的

刚开始写装饰器时,对函数调用方式有疑惑。上面代码最后的语句:test(bar)改变函数原本调用方式很不理解。

经过断点调试和查阅,理解如下:
原函数没有传参,bar()得到的是bar这个函数的执行结果,即等待三秒后执行输出。但是使用装饰器后,高阶函数test1(bar)函数的为原函数附加了一个功能,即输出函数的运行时间,但函数的调用变成将bar的内存地址赋给func,此处使用func()就是执行bar这个函数。
严格意义来说,上面的代码并不符合装饰器的原则。
实现高阶函数b:返回值是函数名。没有改变函数的调用方式。

 import time
#函数的调用方式没有改变
def bar():
time.sleep(3)
print('in the bar')
#装饰器
def test2(func):
print(func)
return func
print('--->',test2(bar))#t=test2(bar) print(t) 二者实现的效果是一样的
t=test2(bar)
t()#等同于bar() bar=test2(bar)
bar()#等同于 run bar

上面内容:把函数bar传给func,print(func),实质是打印下来bar的内存地址,return func 的返回值就是test2(bar)的运行结果。          print('--->',test2(bar))就是将test2(bar)的运行结果(即return func)的运行结果打印下来

第11行中:test2(bar())和test2(bar)的区别?

前者是将bar的运行结果传给test2,(即字符串类型),不符合高阶函数中返回值是函数名这一原则。

后者将bar的内存地址返回给test2,之后执行。

3.函数嵌套
定义:在一个函数体内,用def声明一个新的函数。(注意与函数调用的区别)

4.局部作用域和全局作用域的访问顺序

 #局部作用域和全局作用域的访问顺序
x=0
def test1():
x=1
print(x)
def test2():
x=2
print(x)
def test3():
x=3
print(x)
test3()
test2()
test1()
print(x)

通过上面实现可以看出:

若将test2()注释掉,则将不能访问进入test3()。函数外层输出的x的结果仍旧是0,因为它是全局变量。

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

python 装饰器问题及解决方式的更多相关文章

  1. python装饰器执行顺序

    . python 装饰器 1) 2层装饰器 def decorator(func): # TODO def wrapper(*args, **kwargs): # TODO func(*args, * ...

  2. python 装饰器的缺点以及解决方法

    1.python装饰器的缺点 装饰器可以允许我们在不改变函数或犯方法的调用方式的情况下,添加额外的功能; 如下所示,我们要在中的方法之前增加装饰器check_is_admin,用来判断执行类的方法的用 ...

  3. python 装饰器、递归原理、模块导入方式

    1.装饰器原理 def f1(arg): print '验证' arg() def func(): print ' #.将被调用函数封装到另外一个函数 func = f1(func) #.对原函数重新 ...

  4. Python装饰器详解

    python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...

  5. Python装饰器与面向切面编程

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

  6. 一篇关于Python装饰器的博文

    这是一篇关于python装饰器的博文 在学习python的过程中处处受阻,之前的学习中Python的装饰器学习了好几遍也没能真正的弄懂.这一次抓住视频猛啃了一波,就连python大佬讲解装饰器起来也需 ...

  7. python 装饰器 一篇就能讲清楚

    装饰器一直是我们学习python难以理解并且纠结的问题,想要弄明白装饰器,必须理解一下函数式编程概念,并且对python中函数调用语法中的特性有所了解,使用装饰器非常简单,但是写装饰器却很复杂.为了讲 ...

  8. 利用世界杯,读懂 Python 装饰器

    Python 装饰器是在面试过程高频被问到的问题,装饰器也是一个非常好用的特性, 熟练掌握装饰器会让你的编程思路更加宽广,程序也更加 pythonic. 今天就结合最近的世界杯带大家理解下装饰器. 德 ...

  9. 理解 Python 装饰器看这一篇就够了

    讲 Python 装饰器前,我想先举个例子,虽有点污,但跟装饰器这个话题很贴切. 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个办法就是把内裤改造一下,让它 ...

随机推荐

  1. php----------php安装xhprof扩展和简单使用

    1.下载源码包 https://github.com/longxinH/xhprof  (wget https://github.com/longxinH/xhprof/archive/master. ...

  2. ELK实时日志分析平台环境部署

    为什么要用到ELK一般我们需要进行日志分析场景是:直接在日志文件中 grep.awk 就可以获得自己想要的信息.但在规模较大的场景中,此方法效率低下,面临问题包括日志量太大如何归档.文本搜索太慢怎么办 ...

  3. PHPexcel(2)

    //导出 public function export(){ $xlsData = Db('ent_apply')->select(); Vendor('PHPExcel.PHPExcel'); ...

  4. js 闭包,作用域,this 终结篇(转)

    之前有写过闭包,作用域,this方面的文章,但现在想想当时写的真是废话太多了,以至于绕来绕去的,让新手反而更难理解了,所以就有了此篇文章,也好和闭包,作用域,this告一段落. 第一个问题:什么是闭包 ...

  5. ubuntu window 10 双系统

    https://rufus.ie/ U盘制作工具 http://releases.ubuntu.com/18.04/ubuntu-18.04.2-desktop-amd64.iso   ubuntu ...

  6. IO流(一)

    一.异常 概述 异常就是Java程序在运行过程中出现的错误. 由来 问题也是现实生活中一个具体事务,也可以通过java的类的形式进行描述,并封装成对象.其实就是Java对不正常情况进行描述后的对象体现 ...

  7. python format()用法

    转自 https://www.cnblogs.com/gide/p/6955895.html python2.6开始,新增了一种格式化字符串的函数str.format(),此函数可以快速处理各种字符串 ...

  8. postgresql 自定义聚合函数

    方法1 CREATE OR REPLACE FUNCTION public.sfun_test1( results numeric[], val numeric) RETURNS numeric[] ...

  9. mysql_study_3

    代码: CREATE DATABASE test_01; CREATE DATABASE mysql_shiyan; use mysql_shiyan; CREATE TABLE department ...

  10. 安卓自定义TextView实现自动滚动

    xml文件代码 <com.mobile.APITest.ScrollEditText android:id="@+id/statusEditText" android:lay ...