Python笔记之装饰器(decorator)

python 中一切皆对象,变量是对象,函数也是对象

def  funcName():

return 1

f = funcName                #funcName 是一个函数名,也是一个对象的名字,所以也可以赋值给一个变量,将对象funcName赋值给变量f

f()   #  通过变量f来实现函数funcName函数的调用执行,f()=funcName()

装饰器本质上也是一个函数,作用是可以不修改原有代码的基础上去扩展现有函数功能。它的原理就是讲原函数对象作为参数传递给装饰器函数,并且返回这个原函数执行的结果。这个过程就是装饰器的装饰过程。而我们会

首先我们先看一个简单的例子:假如,我们有2个部门,一个是开发部门,这个功能的技术模块由开发部门提供(也就是说,home ,tv ,movie 这些功能模块的搭建由开发部门建立),

还有一个是运维部门。他们赋值调用这些基础平台的功能(home,tv,moive函数),home,tv,moive 调用,是他们执行调用。)

开发人员搭建的三个功能模块:

def home():

res = print("welcome to my home page")

return res

def tv():

res = print("welcome to my tv page")

return res

def movie():

res = print("welcome to my movie page")

return res

运维部门同事调用三个功能模块:

home()  # 调用并执行home函数

tv() # 调用并执行tv函数

moive()  调用并执行movi函数

运行代码且返回的结果是:

"welcome to my home page"

"welcome to my tv page"

"welcome to my movie page"

这是已经定义好的功能模块,三个函数,一个home ,一个tv ,一个是moive ,需求来了,要给这三个函数加个验证登录的功能。怎么办?

我们先看看,有什么较好的办法实现这个需求功能。在执行home,tv,moive函数之前,我需要先验证。这个验证功能函数如果写呢?

def login(func):

print("Verify, you can accss my web site")

return func

def home():

res = print("welcome to my home page")

return res

def tv():

res = print("welcome to my tv page")

return res

def movie():

res = print("welcome to my movie page")

return res

运维人员需要使用上面的功能模块,就会执行下面的代码调用:

home = login(home)  # 把home 函数作为参数传递给login 并且,login 执行调用了login(),注意,返回这个参数是的函数

home()

tv = login(tv)

tv()

moive = login(moive)

moive()

执行这个代码,返回的结果是:

"Verify, you can accss my web site"

"welcome to my home page"

"Verify, you can accss my web site"

"welcome to my tv page"

"Verify, you can accss my web site"

"welcome to my movie page"

注意:home = login(home)  只要函数带了括号,就会被执行。所以login 函数会执行,home 函数没有带括号只是作为要给参数传递给login ,将login 的执行结果赋值给给这个参数函数 。

上面的代码虽然可以满足user 的需求,没有太多修改现有代码的地方,但是你想想,如果你是运维部门,开发人员提供好了home ,tv ,moive 功能模块,也增加了login 模块,而你需要去调用你的这些函数功能模块,他们在调用调用home,tv,moive 前,都需要先加上:home = login(home),tv = login(tv),moive = login(moive),虽然改动不是很大,但是依然让你修改了现有的代码,你是不是会对开发人员很大的抱怨,虽然,只是每次调用前加上一句代码。

那么我们又什么更好的方法去解决这个问题了,不修改现有代码的基础上。只是扩展了新的功能模块,这就是我们接下来要介绍了的重点-装饰器。

接下来我们就看看有了装饰器,如果去定义一个login的装饰器,且在现有的功能以及使用这个装饰器。因为装饰器本身也是一个函数,所以我接下来就去定义这个装饰器函数。

1 不带参数的函数的功能模块的扩展:

def login(func):  # func 是原函数对象(包含home函数对象/tv函数对象/movie函数对象)作为参数传递给装饰函数login,然后返回这个原函数执行的结果

def inner():

print("Verify,you can access it")

return func()

return inner

@login

def home():

res = print("welcome to my home page")

return res

@login

def tv():

res = print("welcome to my tv page")

return res

@login

def movie():

res = print("welcome to my movie page")

return res

运维人员需要使用上面的功能模块,就会执行下面的代码调用:

home()

tv()

moive()

2 带不确定参数的(动态参数)函数的装饰器原函数不确定带几个参数的装饰器

def login(func):  # 将函数对象作为参数传递给装饰器函数login

def inner(*args,**kwargs):  # 装饰内嵌函数

print("Verify you can access it")  #新功能函数被包含在装饰器内嵌函数里

return func(*args,**kwargs)  #返回原函数对象执行结果,带参数

return inner   #返回装饰内嵌函数对象

@login

def home():

res = print("welcome to my home page")

return res

@login

def tv(name,password):

res = print("welcome %s to my tv page" %name)

return res

@login

def movie(name,id):

res = print("welcome  %s  and %d to my movie page" %(name,id))

return res

基本上掌握上述2种装饰器的用法,能解决大部分的问题。

前面两种都是函数带参数或带动态参数的装饰器的用法,接下来,我们最后介绍装饰器自己带参数的用法,但是它用在什么样的场景呢?例如login进行验证的函数功能,它有很多种验证方式,有账号密码的验证,有LDAP 验证,有AD 验证,有key 的认证等等,运维部门需要什么的验证,就去调用什么的login ,这个我们就可以利用带参数的装饰器来完成。

def loginmaker(*args,**kwargs):   # 把装饰器login再包一层

def login(func):

def inner(*args,**kwargs):

print("Verfiy you can use it ")

return func()

return inner

return login   #返回这个装饰器对象

@loginmaker("calda\bjdong","123445")  # ad 的认证

def home():

res = print("welcom you to my home page")

return res

@loginmaker("daofnda8823ndfafdafds_$ferae") # key 认证

def tv(name,password):

res = print("welcome %s to my tv page")

@loginmaker("joice","1234455") # 账号认证

def moive(nickname,id):

res = print("welcome %s your id is %d" %(nickname,id))

home()

tv()

movie()

时间: 2024-10-15 23:30:11

Python笔记之装饰器(decorator)的相关文章

python笔记 - day4-之装饰器

             python笔记 - day4-之装饰器 需求: 给f1~f100增加个log: def outer(): #定义增加的log print("log") def f1(): outer() #分别调用函数 print("F1") def f2(): outer() #分别调用函数 print("F2") def f100(): outer() #分别调用函数 print("F100") f1() f2

ZMAN的学习笔记之Python篇:装饰器

年前工作事务比较繁琐,我只能用零碎的时间继续学习Python,决定开一个系列的博文,作为自己深入学习Python的记录吧.名字也取好了,就叫<ZMAN的学习笔记之Python篇>~开篇是关于装饰器的,春节假期码的字哈哈~就让我们开始吧! 本文的例子都是自己想的,如果不是很合适,请大家提出宝贵意见哈~谢谢啦! 一.为什么要用“装饰器” 比如我们写了如下一段代码: # 打印0~99 def func(): for i in range(100): print(i) 我们想要监测执行这个函数花费了多

对Python中装饰器(Decorator)的理解与进阶

有时候我们项目中的某些功能做些修改即需要对内部的某些函数添加一些附加功能,但是为了安全起见不想改变函数的源代码以及函数的调用方式,那么装饰器在这个地方会给我们带来很大的帮助. 装饰器(Decorator):(又叫语法糖) 定义:本质是函数,功能(装饰其它函数)就是为其他函数添加附加功能 原则:(1).不能修改被装饰的函数的源代码 (2).不能修改被装饰的函数的调用方式 1.先来实现一个简单的装饰器示例: #!/usr/bin/env python # -*- coding:utf-8 -*- #

python装饰器(decorator)

最近在自学Python,在装饰器这里迷惑了我很久,有几个问题一直困惑着我.1.装饰器的语法原理:2.为什么要用装饰器: 首先来看一下装饰器的原理.总而言之,装饰器就是函数或者类作为函数的返回值.将函数或者类作为装饰器的参数传递之后,装饰器对该函数或者类进行相应操作后再将其返回.这就是装饰器的基本原理.举个例子来讲,我们定义装饰器decorator,定义函数f.其过程便如下:f=decorator(f).这里显得很抽象,我们用具体的例子来描述一下其意思.这里我们定义了一个函数: 1 def rec

Python深入05 装饰器

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果.相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用. 装饰器最早在Python 2.5中出现,它最初被用于加工函数和方法这样

[python基础]关于装饰器

在面试的时候,被问到装饰器,在用的最多的时候就@classmethod ,@staticmethod,开口胡乱回答想这和C#的static public 关键字是不是一样的,等面试回来一看,哇,原来是这样,真佩服我当时厚着脸皮回答的那些问题... OK,先来张图看看装饰器内容: OK,我们留下一个印象,然后我们看实际的场景来操作. 我们先看一个方法: __author__ = 'bruce' def do_sth(): print 'some thing has been done' if __

十、PYTHON 学习之装饰器加深理解

在第六章已经有所介绍,这里看到一篇比较好的文章转过来. 基本概念 装饰器是23z种设计模式之一,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理, Web权限校验, Cache等. 很有名的例子来理解,咖啡,加糖的咖啡,加牛奶的咖啡. 本质上,还是咖啡,只是在原有的东西上,做了"装饰",使之附加一些功能或特性. 例如记录日志,需要对某些函数进行记录 笨的办法,每个函数加入代码,如果代码变了,就悲催了 装饰器的办法,定义一个专门日志记录的装饰器,对需要的函数进行装饰.

Python进阶之装饰器

函数也是对象 要理解Python装饰器,首先要明白在Python中,函数也是一种对象,因此可以把定义函数时的函数名看作是函数对象的一个引用.既然是引用,因此可以将函数赋值给一个变量,也可以把函数作为一个参数传递或返回.同时,函数体中也可以再定义函数. 装饰器本质 可以通过编写一个纯函数的例子来还原装饰器所要做的事. def decorator(func):          def wrap():         print("Doing someting before executing fu

1.16 Python基础知识 - 装饰器

Python中的装饰器就是函数,作用就是包装其他函数,为他们起到修饰作用.在不修改源代码的情况下,为这些函数额外添加一些功能,像日志记录,性能测试等.一个函数可以使用多个装饰器,产生的结果与装饰器的位置顺序有关. 装饰器基本形式: @装饰器1 def 函数1: 函数体 相当于:==> 函数1 = 装饰器1(函数1) 装饰器特点: 1.不修改源代码的调用方式 2.不修改源代码内容 3.装饰器有高阶函数与递归函数相融合的特点 多个装饰器修饰,示例: @foo @spam def bar():pass