装饰器 中的“器”代指函数

所以装饰器本质是函数,用来装饰其它函数。例如:为其它函数添加其他功能

实现装饰器需要的知识:  高阶函数+嵌套函数 == 装饰器

1、函数就是“变量”

  函数就是“变量”说的就是 函数在内存的存储和回收 和变量类似。

2、高阶函数(函数调用另一个函数,把函数名作为另一个函数的参数)

 def foo():
print("foo ...") def fun(fun):
print(fun)
fun() # fun = foo 相当于foo 和 fun 所指的内存一样
fun(foo) #结果 <function foo at 0x0000000003C6E8C8>
# foo ...

我们发现 foo.. .执行了 ,是因为foo 和 fun 所指的内存一样 ,函数即变量 可以赋值

但是我们为什么要多此一举,这样执行呢? 来看下面代码:

 import time
def foo():
time.sleep(1)
print("foo ...") def fun(fun):
start_time = time.time()
fun() # fun = foo 相当于foo 和 fun 所指的内存一样
stop_time = time.time()
print("cost time %s" %(stop_time - start_time)) foo()
fun(foo) #结果:foo ...
# foo ...
# cost time 1.0000572204589844

我们发现我们实现了装饰一个函数 我们执行 foo() 和 fun(foo) 效果不一样 ,fun装饰了 foo 函数

现在 我们已经满足了原则1 :不改变源代码

我们再看另一个函数:

 import time
def bar():
time.sleep(3)
print('in the bar')
def test2(func):
print(func)
return func
print(test2(bar))
print("------------------")
bar=test2(bar)
bar() #run bar #结果
# <function bar at 0x0000000003C6E8C8>
# <function bar at 0x0000000003C6E8C8>
# ------------------
# <function bar at 0x0000000003C6E8C8>
# in the bar

我们满足了两个原则

3、嵌套函数

 def grandpa():
# x=1
def dad(): #只是定义阶段
x=2
def son(): #只是定义阶段
x=3
print (x)
son() #必须在这个位置执行
dad() #必须在这个位置执行 运行dad
grandpa()

看下面的例子: 假如我们实际场景有100个函数(这里列举两个),这里的函数已经上线运行,现在需要为每一个函数增加一个日志。如果用下面的方式相当于修改了函数的源代码,万一产生错误那么后果很严重(业务崩溃)。

 __author__ = "WSX"

 def fun1():
print("fun1")
logger("")
def fun2():
print("fun2")
logger("") def logger( fun):
print("Logger %s" %fun)
fun1()
fun2()

所以函数一旦写好不要去修改函数源代码。

这里我们就需要装饰器。

装饰器的原则:

1、不会修改被修饰的函数源码

2、不要修改函数的调用方式

现在我们来写一个简单的装饰器:

 import time
def timmer(func): #这是一个装饰器 ,计算时间
def warpper(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs)
stop_time=time.time()
print('the func run time is %s' %(stop_time-start_time))
return warpper @timmer
def test1():
time.sleep(3)
print('in the test1')
test1()
结果:
in the test1
the func run time is 3.0001718997955322

上面的代码满足装饰器的原则。现在来分析程序:

@timmer  相当于test1 = timmer(test1)

现在我们就完成了一个装饰器。timmer是装饰器    test1是需要被装饰的函数

下面是老男孩教育Alex写的复杂的带函数返回值的装饰器(堪称高潮):
 __author__ = "Alex Li"
import time
user,passwd = 'alex','abc123'
def auth(auth_type):
print("auth func:",auth_type)
def outer_wrapper(func):
def wrapper(*args, **kwargs):
print("wrapper func args:", *args, **kwargs)
if auth_type == "local":
username = input("Username:").strip()
password = input("Password:").strip()
if user == username and passwd == password:
print("\033[32;1mUser has passed authentication\033[0m")
res = func(*args, **kwargs) # from home
print("---after authenticaion ")
return res
else:
exit("\033[31;1mInvalid username or password\033[0m")
elif auth_type == "ldap":
print("搞毛线ldap,不会。。。。") return wrapper
return outer_wrapper def index():
print("welcome to index page")
@auth(auth_type="local") # home = wrapper()
def home():
print("welcome to home page")
return "from home" @auth(auth_type="ldap")
def bbs():
print("welcome to bbs page") index()
print(home()) #wrapper()
bbs()
采用三层嵌套,第二层用于返回需要被装饰的函数的返回值。
 

Python 之 装饰器的更多相关文章

  1. Python各式装饰器

    Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...

  2. Python札记 -- 装饰器补充

    本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...

  3. python基础——装饰器

    python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...

  4. 【转】详解Python的装饰器

    原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...

  5. 两个实用的Python的装饰器

    两个实用的Python的装饰器 超时函数 这个函数的作用在于可以给任意可能会hang住的函数添加超时功能,这个功能在编写外部API调用 .网络爬虫.数据库查询的时候特别有用 timeout装饰器的代码 ...

  6. python 基础——装饰器

    python 的装饰器,其实用到了以下几个语言特点: 1. 一切皆对象 2. 函数可以嵌套定义 3. 闭包,可以延长变量作用域 4. *args 和 **kwargs 可变参数 第1点,一切皆对象,包 ...

  7. 理解Python中的装饰器//这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档

    转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档 ...

  8. python基础—装饰器

    python基础-装饰器 定义:一个函数,可以接受一个函数作为参数,对该函数进行一些包装,不改变函数的本身. def foo(): return 123 a=foo(); b=foo; print(a ...

  9. 详解Python的装饰器

    Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...

  10. 关于python的装饰器(初解)

    在python中,装饰器(decorator)是一个主要的函数,在工作中,有了装饰器简直如虎添翼,许多公司面试题也会考装饰器,而装饰器的意思又很难让人理解. python中,装饰器是一个帮函数动态增加 ...

随机推荐

  1. python第三十二天-----算法

    算法(Algorithm):一个计算过程,解决问题的方法时间复杂度:用来评估算法运行效率的一个东西ps:在日常使用中,请使用sort(),because no zuo no die! 1.冒泡排序:指 ...

  2. .Net Memory Profiler入门

    简介:http://www.cnblogs.com/wmlunge/archive/2013/01/08/2850809.html 实践: http://www.cnblogs.com/eaglet/ ...

  3. [git更新中]版本控制工具git初步使用

    逐渐开始写规模稍大的程序, 如果在像以前一样每写完一次保存一个版本, 修改起来太蛋疼了, 而且还会忘记都有修改过哪里, 最终如果写完的话, 各种不方便, 于是便开始接触版本控制工具. 因为是在Linu ...

  4. Less known Solaris features: svccfg editprop (ZT)

    http://www.c0t0d0s0.org/archives/7675-Less-known-Solaris-features-svccfg-editprop.html Sometimes sma ...

  5. 需要network lightweight filter disk 上的文件netft.sys

    小米wifi在win10下安装不成功,需要network lightweight filter disk 上的文件ntflt.sys 默认路径有问题,改成下面的路径好了! 选择下面第一个路径安装成功了 ...

  6. CSS3 高级属性

    尽管现代浏览器已经支持了众多的CSS3属性,但是大部分设计师和开发人员貌似依然在关注于一些很“主流”的属性,如border-radius.box-shadow或者transform等.它们有良好的文档 ...

  7. ios配合iTuns提取应用Documents下的文件到本地

    出处:http://blog.csdn.net/jianandjan/article/details/50442988 有一些App需要通过使用iTunes让用户上传和下载文档.要让iOS程序支持iT ...

  8. springBoot数据库jpa+对接mybatis

    1  spring Data jpa hibernate引领数据访问技术,使用orm对象关系映射来进行数据库访问,通过模型和数据库进行映射,通过操作对象实现对数据库操作,把数据库相关操作从代码中独立出 ...

  9. nginx 代理参数介绍

    2)我们可以看到nginx文件夹内有一个conf文件夹,其中有好几个文件,其他先不管,我们打开nginx.conf,可以看到一段: 这段代码在server里面,相当于一个代理服务器,当然可以配置多个. ...

  10. SQL IN, NOT IN, EXISTS, NOT EXISTS

    IN与EXISTS执行流程 IN:在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选.所以相对内表比较小的时候,in的速度较快.(IN时不对NULL进行处理) EX ...