#统计函数运行时间
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. Mybatis下的sql注入

    以前只知道mybatis框架下,order by后面接的是列名是不能用#{},这样不起效果,只能用${},这样的话就可能产生sql注入.后来发现其实还有另外两种情况也是类似的: 1.order by ...

  2. FB面经 Prepare: LCA of Deepest Nodes in Binary Tree

    给一个 二叉树 , 求最深节点的最小公共父节点 . retrun . 先用 recursive , 很快写出来了, 要求用 iterative . 时间不够了... Recursion: 返回的时候返 ...

  3. Java基础(Java补码)

    原码,反码,补码是java数值运算的基础,在计算机程序中,数值运算是基于二进制的,也就是说底层是二进制运算.而数值有正数与负数,二进制只有0和1,如何表示负数,如何进行正负数的运算,这就是原反补的意义 ...

  4. Oracle函数中对于NO_DATA_FOUND异常处理的研究

    一直以来有一个困惑,一直没解决,昨天一哥们问我这个问题,决心弄清楚,终于得到了答案.先看下面这个函数: create or replace function fn_test(c_xm varchar) ...

  5. zookeeper注册与发现

    pom.xml添加如下引用: <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId ...

  6. LapSRN

    Deep Laplacian Pyramid Networks for Fast and Accurate Super-Resolution 解决问题: 1.bicubic预处理上下采样,计算复杂度高 ...

  7. Linux机器重启情况查询

    在实际开发过程中,有时可能发现有一些服务器的进程挂了,查询相关错误日志也没有头绪.此时需要考虑是否是由于机器重启导致的错误 使用命令last reboot来查看是否机器自动重启 导致服务器重启的原因有 ...

  8. Java SE中的Synchronized

    1 引言 在多线程并发的编程中Synchronized一直是元老级的角色,很多人会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化以后,有些情况下它并不那么重了. ...

  9. 手机APP应用外网访问本地WEB应用

    手机APP应用外网访问本地WEB应用 本地安装了WEB服务端,手机APP应用只能在局域网内访问本地WEB,怎样使手机APP应用从公网也能访问本地WEB? 本文将介绍具体的实现步骤. 1. 准备工作 1 ...

  10. 第一章 Python程序语言简介

    第一节 Python概述 1. 什么是Python Python是一种 解释型.面向对象.动态数据类型 的高级程序设计语言.由Guido van Rossum与1989年发明,第一个公开发行版本发行于 ...