掌握Python闭包的使用以及装饰器的使用

本文深入浅出地讲解了闭包的概念及其在JavaScript中的应用,并通过实例详细解析了装饰器的工作原理及如何使用。

闭包

  • 闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
  • 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包。

 

def func(number):
    print("******func******")
    def func_inner(number_2):
        print("******func_inner******")
        print(number + number_2)
    print("************")
    return func_inner


result = func(100)
result(100)
result(200)

# Output
******func******
************
******func_inner******
200
******func_inner******
300
  • 一般在函数结束时,会释放临时变量,但在闭包中,由于外函数的临时变量在内函数中用到,此时外函数会把临时变量与内函数绑定到一起,这样虽然外函数结束了,但调用内函数时依旧能够使用临时变量,即闭包外层的参数可以在内存中进行保留

装饰器

  • 装饰器原理理解起来难?不存在的,下面短短几行代码就讲清楚了
def decorate(func):
    def inner():
        print("***inner***")
        func()
    return inner

def test1():
    print("***test1***")

def test2():
    print("***test2***")

# output
test1 = decorate(test1)
test1()
test2= decorate(test2)
test2()

装饰器的原理清楚了,如何使用呢?请看如下代码

def decorate(func):
    print('***func***')
    def decorate_in():
        print('***decorate_in***')
        func()
    return decorate_in

@decorate
def test1():
    print('***test1***')

@decorate
def test2():
    print('***test2***')

# output
***decorate_in***
***test1***
***decorate_in***
***test2***

是不是很好懂?第一个装饰器相当于test1 = decorate(test1),第二个装饰器相当于test2 = decorate(test2)。需要注意的是一个函数被两个装饰器装饰时,应该先装饰里层的,再装饰外层的。代码如下:

def Smile(func_name):
    def Smile_inner():
        return "<Smile> " + func_name() + " </Smile>"

    return Smile_inner


def Laugh(func_name):
    def Laugh_inner():
        return '<Laugh>' + func_name() + '</Laugh>'

    return Laugh_inner


@Laugh
@Smile
def test1():
    print('***test1***')
    return "TEST"

print(test1())

# output
***test1***
<Laugh><Smile> TEST </Smile></Laugh>
  • 当原函数需要传参时,装饰器(即闭包)的内函数以及内函数中调用原函数的部分都需要加上相同数量的参数。
  • 当原函数有返回值时,装饰器(即闭包)的内函数也需要有返回值,且调用原函数的部分需要将原函数的返回值用一个变量进行接收。
  • 为了使装饰器具有通用性,即能够装饰有参、无参、有返回值和无返回值的函数,直接在定义装饰器的时候就将不定长参数和返回值都写上,因为不定长参数包括了零个或零个以上的参数,而无返回值时相当于返回了None

带参数的装饰器

  • def colors(c):
        def set_color(func):
            def red(*word):
                return '\033[31;1m%s\033[0m' % func(*word)
    
            def green(*word):
                return '\033[32;1m%s\033[0m' % func(*word)
    
            adict = {'red': red, 'green': green}
            return adict[c]
    
        return set_color
    
    
    @colors('red')
    def hello():
        return 'Hello world!'
    
    
    @colors('green')
    def welcome(word):
        return 'Hello %s' % word
    
    
    if __name__ == '__main__':
        print(hello())  # -> hello = set_color(hello)
        print(welcome('China'))
    
    # output
    Hello world! # 效果:输出字体颜色是红色
    Hello China # 效果:输出字体颜色是绿色

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诗雅颂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值