python 装饰器

装饰器的用途:当写好一些函数,想对这些函数添加额外的附加功能(例如:登录验证,授权,日志等),而不改变原来函数的写法和调用,就需要用到装饰器。

装饰器特点:

  • 代码重用
  • 不改变已写函数的本身
  • 不影响函数的返回结果
示例一

我有下面两个函数,很easy。我想对这两个添加一个功能,再执行之前添加个登录的功能。

def do():
    print "do something"

def gan():
    print "gan something"

如果不用装饰器,你可能会这么写

def do():
    print "login"
    print "do something"

def gan():
    print "login"
    print "gan something"

do()
gan()

执行结果:
    login
    do something
    login
    gan something

代码重用,太tmd的low了,是不是。于是你换了个招数

def begin():
    print "login"
def do():
    begin()
    print "do something"
def gan():
    begin()
    print "gan something"
do()
gan()

你定义了一个新的函数,begin(),他可以完美的是现实了代码复用。但是还是对原来的函数进行了改动。我们已经做好的功能要尽可能少的改动,为了稳定。所以在这里装饰器应运而生。其实装饰器的道理很简单,就是像上面函数一样,函数套函数。

将上面功能改为装饰器实现

def begin(fun):
    def inner():
        print "login"
        return fun()
    return inner

@begin
def do():
    print "do something"
@begin
def gan():
    print "gan something"

记住个概念,函数即使变量。所以可以把一个函数的名称当成实参传递给另外一个函数。你print一个函数名时会打印出内存地址
上面装饰器就是最基本的写法,需要注意几点:

  • “@begin”是python的语法糖,即为调用装饰器。此时do()相当于 do = begin(do)
  • 定义装饰器时返回的值为 函数地址 “return inner”而不是“return inner()”。因为下面你调用的时候直接do(),而不是do
示例二,函数单个传参
def begin(fun):
    def inner(args):
        print "login"
        return fun(args)
    return inner

@begin
def do(name):
    print "%s do something" %name


do("Reba")

结果:
login
Reba do something

将函数的参数传给inner函数,inner函数在传给fun函数

示例三,由于装饰器用来装饰很多函数,所以参数很有可能不固定,所以传递多个参数
 def begin(fun):
    def inner(*args,**kwargs):
        print "login"
        return fun(*args,**kwargs)
    return inner

@begin
def do(name,age):
    print "%s do something" %name
    print "age:",age
do("Reba","22")
结果:
    login
    Reba do something
    age: 22
示例四 ,在函数执行前和执行后都加入装饰器。用的不多,到时候再看也行
def Filter(before_func, after_func):
    def outer(main_func):
        def wrapper(request, kargs):

            before_result = before_func(request, kargs)
            if (before_result != None):
                return before_result;

            main_result = main_func(request, kargs)
            if (main_result != None):
                return main_result;

            after_result = after_func(request, kargs)
            if (after_result != None):
                return after_result;

        return wrapper

    return outer


@Filter(Before, After)
def Index(request, kargs):
    print 'index'

Index("11111111","22222222")
结果:
    before
    index
    after

装饰器的用处还是挺多的,希望对你有些帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值