python成长之路【第四篇】:装饰器

实现装饰器的知识储备:

示例:
	def f1():
		print("f1")

1、函数即“变量”
	#上面的示例中,函数f1为变量,它指向内存地址。而f1()表示函数执行。
2、高阶函数
	a:把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)。
	b:返回值中包含函数名(不修改函数的调用方式)。
3、嵌套函数
	将一个函数放在另外一个函数里面。
	
装饰器 = 高阶函数 + 嵌套函数

装饰器定义:本质是函数。(装饰其他函数)就是为其他函数添加附加功能。
装饰器原则:

  1、不能修改被装饰的函数的源代码。
  2、不能修改被装饰的函数的调用方式。

 

装饰器代码剖析:

假如A公司有这么一个需求,公司临时规定将某块业务加上访问权限,因为代码太多,又不想改变原有封装好的代码,于是码农提出一个解决方法:装饰器。

原始代码:

def f1():
    #print("welcome to login...")  #需求是在这块加上验证
    print("f1...")
f1()   #执行函数

添加一个验证模块后,功能是实现了,但是改变了原有的调用方式:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#author chenjing

def auth_login(func):   #func = f1
    def inner():
        print("welcome to login...")   #验证的内容加载这里
        func()     #func() = f1(),相当于执行f1()
    return inner    #返回inner函数体

def f1():
    #print("welcome to login...")  #需求是在这块加上验证
    print("f1...")

result = auth_login(f1)   #等于inner函数(包括它下面那一段代码)
result()    #执行函数

继续修改,保证原有的调用方式不受影响。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#author chenjing

def auth_login(func):   #func = f1
    def inner():
        print("auth user ...")   #认证模块
        func()     #func() = f1(),相当于执行f1()
    return inner    #返回inner函数体

@auth_login    #@auth_login是Python默认封装好的一种方法,它就是装饰器,功能相当于result = auth_login(f1)
def f1():
    print("I'm f1")

f1()    #执行函数 

输出结果:

auth user ...
I'm f1

到目前为止,f1业务好像已经完成了,这时f2业务又提了一个需求,f2调用时,需要往函数里面传递一个参数。coding...

那么怎么办呢?那我们定义另外一个装饰器,而这个装饰器是可以接收参数的。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#author chenjing

def auth_login(func):   #func = f1
    def inner():
        print("auth user ...")   #认证模块
        func()     #func() = f1(),相当于执行f1()
    return inner    #返回inner函数体

def auth_login_arg(func):
    def inner(arg):
        print("auth user arg...")
        func(arg)
    return inner

@auth_login    #@auth_login是Python默认封装好的一种方法,相当于result = auth_login(f1)
def f1():
    print("I'm f1")
f1()    #执行函数

@auth_login_arg    #调用新装饰器
def f2(arg):    #参数
    print("I'm f2",arg)
f2("new programs")  #传入参数

输出结果:

auth user ...
I'm f1
auth user arg...              #请看f2函数的输出
I'm f2 new programs

到目前为止,f2业务好像已经完成了,这时f3业务又提了一个需求,f3调用时,需要往函数里面传递几个参数。coding...

这。。。程序员果然不是人干的。。我们还是看下面代码吧。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#author chenjing

def auth_login(func):   #func = f1
    def inner():
        print("auth user ...")   #认证模块
        func()     #func() = f1(),相当于执行f1()
    return inner    #返回inner函数体

def auth_login_arg(func):
    def inner(arg):
        print("auth user arg...")
        func(arg)
    return inner

def auth_login_args(func):
    def inner(*args,**kwargs):    #动态参数
        print("auth user...")    #认证模块
        func(*args,**kwargs)    #动态参数
    return  inner

@auth_login    #@auth_login是Python默认封装好的一种方法,相当于result = auth_login(f1)
def f1():
    print("I'm f1")
f1()    #执行函数

@auth_login_arg    #调用新装饰器
def f2(arg):    #参数
    print("I'm f2",arg)
f2("new programs")  #传入参数

@auth_login_args
def f3(name,age):
    print("I'm f3...",name,age)
f3("Colin Chen",18)

输出结果:

auth user ...
I'm f1
auth user arg...
I'm f2 new programs
auth user...
I'm f3... Colin Chen 18

完美。需求都完成了,心情那叫一个好。

 

posted @ 2016-08-17 21:17  wooya  阅读(256)  评论(0编辑  收藏  举报