装饰器( decorate )

 装饰器分步解释-形成过程:

#-*- coding: UTF-8 -*-

#示例1:
def deco(p_args):
    def pack():
        print('haha,i am deco fun')
        print('i want to use parent fun arg: '+p_args) 
        print('haha,i am deco fun--finished\n')
    return pack

deco('abc') #执行结果无返回值
deco('abc')() #执行结果同示例2

#示例2:
def deco(p_args):
    def pack():
        print('haha,i am deco fun')
        print('i want to use parent fun arg: '+p_args) 
        print('haha,i am deco fun--finished\n')
    return pack() #需要加上小括号,否则pack函数不会被执行

deco('abc') #执行结果返回如下:
#haha,i am deco fun
#there are 2 args.they are:
#haha,i am deco fun--finished

#示例3:
def myf():
    print('i want to be decorated.')

def deco(fun):
    def pack():
        print('haha,i am deco fun')
        #print('i want to use parent fun arg: '+p_args) 
        fun()
        print('haha,i am deco fun--finished\n')
    return pack #此处不加括号,deco(myf)执行结果无返回。同示例1

deco(myf) #执行结果无返回。
deco(myf)() #执行结果同示例4

#示例4:
def myf():
    print('i want to be decorated.')

def deco(fun):
    def pack():
        print('haha,i am deco fun')
        #print('i want to use parent fun arg: '+p_args) 
        fun()
        print('haha,i am deco fun--finished\n')
    return pack() #加括号,deco(myf)执行结果输出如下,同示例2

deco(myf) #将myf函数传给deco函数的参数fun。
#haha,i am deco fun
#i want to be decorated.
#haha,i am deco fun--finished


#示例5:
def myf():
    print('i want to be decorated.')

def deco(fun):
    def pack():
        print('haha,i am deco fun')
        #print('i want to use parent fun arg: '+p_args) 
        fun()
        print('haha,i am deco fun--finished\n')
    return pack #此处不加括号,而是在最外面的函数执行的时候再加括号执行,如deco(myf)()

#deco(myf)()的执行结果等价于如下,输出结果同示例4:
myf1 = deco(myf)
myf1()
#haha,i am deco fun
#i want to be decorated.
#haha,i am deco fun--finished

#此处的变量myf1跟myf没有任何关系,只是将deco(myf)这个函数赋予了变量myf1,然后再通过myf1()的方式执行该函数。所以可以将myf1重新写为myf,就成了装饰器的效果,如示例6。
myf = deco(myf)
myf()


#示例6--装饰器:
def deco(fun):
    def pack():
        print('haha,i am deco fun----')
        #print('i want to use parent fun arg: '+p_args) 
        fun()
        print('haha,i am deco fun--finished\n')
    return pack #此处不加括号,而是在最外面的函数执行的时候再加括号执行,如deco(myf)()

@deco
def myf():
    print('i want to be decorated,6.')
myf()

 

装饰器中的函数参数传递:

def deco(fun):
    def pack(*args,**kwargs): #这样写可以传递任意参数。也可以直接写name,age,只是这样在其他函数调用的时候会出错,因为其他函数的参数可能并不是name,age等。。。
        print('haha,i am deco fun')
        print('there are %d args.they are: %s %d' %(len(args),args[0],args[1])) #调用原函数的参数
        fun(*args,**kwargs)
        print('haha,i am deco fun--finished')
    return pack

@deco  #将sayhi传给deco的参数fun
def sayhi(name,age):
    print('helo,i am %s ,my age is %d.'%(name,age))


sayhi('LiuXue',20)
#返回结果:
haha,i am deco fun
there are 2 args.they are: LiuXue 20
helo,i am LiuXue ,my age is 20.
haha,i am deco fun--finished

 

#定义函数:
def hello(*args,**kw):
    print 'ab'
    print args
    print kw
args=range(1,5)

hello(args) #返回值:
ab
([1, 2, 3, 4],)
{}

#定义装饰函数:
def dec(fun):
    def wrapper(*args,**kw):
        print 'do sth. before'
        fun(*args,**kw)
        print 'do sth. after'
    return wrapper

dec(hello(args)) #将hello函数及参数当做变量赋予dec,只相当于直接执行hello(args),返回值:
ab
([1, 2, 3, 4],)
{}


p=dec(hello)
p(args)

dec(hello)(args) #将函数当做变量赋予dec,然后通过变量调用函数,再赋予变量变量,返回值:
do sth. before
ab
([1, 2, 3, 4],)
{}
do sth. after

 

def dec(fun):
    def wrapper(*args,**kw):
        print 'do sth. before'
        fun(*args,**kw)          #此处如果改为 return fun(*args,**kw),则下一句print 'after'不会再执行。在函数中,遇到第一个return则不会再执行后面的语句,如果返回两个值,可以写在同一行。如果用了return,函数执行完会得到结果,没有return则无返回值
        print 'do sth. after'
    return wrapper

@dec #通过@调用装饰函数
def hello(*args,**kw):
    print 'ab'
    print args
    print kw
args=range(1,5)

hello(args)

 装饰器自身接收参数:

# -*- coding: UTF-8 -*-

def deco(darg): #装饰函数的参数
    print darg
    def getFun(func):
        def pack(name,age): #这样写可以传递任意参数。也可以直接写name,age,只是这样在其他函数调用的时候会出错,因为其他函数的参数可能并不是name,age等。。。
            print('haha,i am darg: '+darg) #装饰函数的参数可以传入使用
            print('there are  args.they are: %s %d' %(name,age)) #调用原函数的参数
            func(name,age)
            print('haha,i am deco fun--finished')
        return pack
    return getFun

@deco('abc') #装饰函数调用参数‘abc’
def sayhi(name,age):
    m=15
    print('helo,i am %s ,my age is %d.'%(name,age))


name='LiuXue'
age=20
sayhi(name,age)
# #返回结果:
abc
haha,i am darg: abc
there are  args.they are: LiuXue 20
helo,i am LiuXue ,my age is 20.
haha,i am deco fun--finished

 

参考:https://javaforall.cn/165489.html

 

posted on 2016-03-09 15:24  momingliu11  阅读(580)  评论(0编辑  收藏  举报