python中函数的闭包和装饰器

        对于一般的函数我们无法通过直接引用来对嵌套函数中的内层函数进行操作,而闭包很好地解决了这一问题,示例如下:

def power(exp):
    def exp_of(base):
        return base ** exp
    return exp_of

square = power(2)
cube = power(3)

print(square(2), square(3))
print(cube(2), cube(3))
## 4 9
## 8 27

         同时使用闭包和nonlocal时可以使得函数内部参数不被初始化。

def outer():
    x=0
    y=0
    def inner(x1, y1):
        nonlocal x, y
        x+=x1
        y+=y1
        print(f"Now,x={x},y={y}")
    return inner

move = outer()
move(1, 2)
move(-2, -3)
## Now,x=1,y=2
## Now,x=-1,y=-1
# 可以看见每次调用时,函数内部的x和y并没有被初始化。

        与闭包相反,我们可以通过将函数作为函数的参数:

def myfun():
    print("正在调用myfun...")

def report(func):
    print("开始调用函数")
    func()
    print("函数调用完毕")

report(myfun)
## 开始调用函数
## 正在调用myfun...
## 函数调用完毕

通过使用装饰器,我们可以避免再去函数中直接调用函数。

import time

def times(func):
    def call_func():
        print("开始运行该程序...")
        start = time.time()
        func()
        stop = time.time()
        print(f"一共耗费了{(stop-start)*1000:.2f}ms")
    return call_func

@times
def myfun():
    time.sleep(2)
    print("I Love Cloud")

myfun()

## 开始运行该程序...
## I Love Cloud
## 一共耗费了2001.42ms

        装饰器的实现使用到了闭包的方法,其中的@times便是相当于 myfun = times(myfun)。

        对于多个修饰器同时使用在同一个函数上也是可行的。

def add(func):
    def inner():
        x=func()
        return x+1
    return inner

def square(func):
    def inner():
        x=func()
        return x*x
    return inner

def cube(func):
    def inner():
        x=func()
        return x*x*x
    return inner

@square
@add
@cube
def myfun():
    return 2

print(myfun())
## 81
#可以看出,函数先调用cube,再调用add,最后调用square

        给装饰器传递参数:

import time

def logger(msg):
    def times(func):
        def call_func():
            start = time.time()
            func()
            stop = time.time()
            print(f"[{msg}]一共耗费了{stop-start:.2f}s")
        return call_func
    return times

@logger(msg="A")
def funa():
    time.sleep(1)
    print("正在调用funa...")

@logger(msg="B")
def funb():
    time.sleep(1)
    print("正在调用funb...")

funa()
funb()

## 正在调用funa...
## [A]一共耗费了1.00s
## 正在调用funb...
## [B]一共耗费了1.00s

对于给修饰器传递参数,无非是多了一层函数的嵌套。其等价于

import time

def logger(msg):
    def times(func):
        def call_func():
            start = time.time()
            func()
            stop = time.time()
            print(f"[{msg}]一共耗费了{stop-start:.2f}s")
        return call_func
    return times

def funa():
    time.sleep(1)
    print("正在调用funa...")

def funb():
    time.sleep(1)
    print("正在调用funb...")

funa = logger(msg="A")(funa)
funb = logger(msg="A")(funb)

funa()
funb()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值