python(4) - 装饰器

由于函数也是一个对象,既然是对象就可以将它赋给变量,通过变量来调用该函数

def now():
    print('2016-01-01')

f = now              #注意,这里不能带(),函数带上()表示执行函数的意思
f.()                     #这里带上括号了,就是执行该函数,通过变量f调用

2016-01-01

函数有一个__name__方法,用来显示函数的名字:

>>> now.__name__
'now'
>>> f.__name__
'now'
>>>

OK,接下来详细介绍一下装饰器,因为装饰器比较抽象,所以我们通过代码来理解一下:

还是先假设一个情景:A公司有一个系统,用户登录后,可以访问主页,可以听音乐,可以看视频,源码是这样的:

def home(name):
    print("Welcom %s to home!" % name)

def music(name):
    print("Welcom %s to music!" % name)

def video(name):
    print("welcome %s to video!" % name)

如果用户张三想看视频,那么通过如下方式:

video("zhangsan")

A公司这个系统运营了很久,有了很多用户,越来越大,后来维护费用太高,A公司渐渐没钱了, 这时公司决定对用户进行收费, 那么就需要加上验证功能, 交了钱的用户可以听音乐,看视频, 不交钱的只能看看主页,但是又不能改变用户的习惯, 用户原来使用video(“张三”) 来看视频,那修改以后也得这样看视频;我们都知道,已经运行的代码是不可以直接修改的,那我们怎么办呢?

那既然不能修改原来的代码,那我就在原来的代码外面写一个验证的函数:

def login(func):         #接收一个函数作为参数
    print("用户验证通过。。。。")
    return func         #将函数返回

接下来就是让用户在看视频之前先运行login函数来验证身份,那我们这样进行赋值:

video = login(video)

当用户张三要看视频的时候,还是按照来的方法

video("张三")

当用户敲完回车后,发生了什么,分析一下:

这里video(“张三”) 实际上就是 login(video)(“张三”)

拆分一下,先看看login(video)的执行结果:

先打印用户验证通过的信息,实际就是验证了用户的身份。然后将video的函数返回,注意返回原是函数(没有带括号);

然后变成了video(“张三”),  看到了视频。其实就是在看视频之前执行了身份验证。

理解了之后,就好说了,装饰器实际上就是干了最后一步的活,即video = login(video)。 看一下,装饰器是怎么用的,还是上面的例子,login()函数已经写好了,接下来要用到music和video上

@login
def music(name):
    print("Welcom %s to music!" % name)

@login
def video(name):
    print("welcome %s to video!" % name)

这样看起来好像很完美,但是实际上是有问题的;为什么呢?

我们仔细想一下验证过程,因为这里是模拟的,没有任何验证程序,只是打印了验证通过,而实际中,验证是需要有用户名密码信息的,但在login(tv)时,只是把tv这个函数传递给了login, 用户名”张三”根本没有传递进去,又如何验证呢??  接下来的一篇介绍如何传递多参数。

posted @ 2016-02-28 23:38  黄小墨  阅读(243)  评论(0编辑  收藏  举报