python新手入门笔记(十二)——闭包处理及装饰器

闭包处理

在函数内部再定义一个函数,并且这个函数用到了外部函数的变量,那么
将这个函数以及用到的这些变量,称之为闭包。

def outer(num1):
    def inner(num2):
        print(f'在inner函数中,num2的值是{num2}')
        return num1 + num2

    return inner

res = outer(10)
print(res(100))

闭包有什么作用:
可以读取函数内部的变量
让这些变量的值始终保持在内存中,不会在f1调用后被自动清除。

大白话的意思就是,我们需要一些数据存在得长一点,一些数据用完就扔,但不可能一次次把两者都重复输入,此时闭包就体现出它的作用。

nonlocal函数

nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量。

# 累加生效
def outer(x):
    def inner(y):
        nonlocal x
        x += y
        return x
    return inner

res = outer(10)
print(res(1)) # 11
print(res(2)) # 13

装饰器

在原来的函数基础上增加一些功能。
遵循开放 封闭原则

装饰没有参数的函数

def check_login(func):
    def inner():
        print('hahaha')
        return func()

    return inner

@check_login
def f1():
    # check_login()
    print('f1')

f1()

用途很广,最典型之一是为登陆功能加上验证功能。

被装饰的函数有参数

def check_login(func):
    def inner(a,b):
        print(f'函数{func.__name__}运行了')
        return func(a,b)

    return inner


@check_login
def f1(a,b):
    # check_login()
    return a+b



f1(4,5)

被装饰的函数有不定长参数

def outer(func):
    def inner(*args,**kwargs):
        print(f'函数{func.__name__}运行了')
        func(*args,**kwargs)
    return inner

@outer
def foo(x,y,z):
    print(x+y+z)

foo(4,5,6)

装饰器的返回值

无返回值:

from time import ctime # 捕获时间
def timefunc(func):
    def wrapped():
        print(f'{func.__name__}运行于{ctime()}')
        func()
    return wrapped

@timefunc
def foo1():
    print('foo-----------------')

foo1()

有返回值:

from time import ctime # 捕获时间
def timefunc(func):
    def wrapped():
        print(f'{func.__name__}运行于{ctime()}')
        func() # 返回None的关键点
    return wrapped
@timefunc
def foo2():
    return 'cccccccccccccccccccc'
print(foo2()) # 返回None

如果想返回设定内容:

from time import ctime
def timefunc(func):
    def wrapped():
        print(f'{func.__name__}运行于{ctime()}')
        return func() # return 一个函数对上述两种情况都是用
    return wrapped
@timefunc
def foo2():
    return 'cccccccccccccccccccc'
print(foo2())

小结:写装饰器时,内部不要直接调用函数,而是返回return函数的执行结果

装饰器本身有参数

def outer_s(printRes = False):# 再加一层函数用来带参数
    def outer(func):# 如果只有两层,是不能带参数的,这一层只能带被装饰的函数参数。
        def inner(*args,**kwargs):
            print(f'函数{func.__name__}运行了')
            if printRes:
                print(func(*args,**kwargs))
            else:
                return func(*args,**kwargs)
        return inner
    return outer

@outer_s(True)
def foo(s,length):
    return s[:length]

foo('hello world',5)

类装饰器

用类做一个装饰器,用call方法给某个方法添加功能。
不能执行的dog()。

class Dog:
    def run(self):
        pass

dog = Dog()
dog.run()
dog()

能执行的dog():

class Dog:
    def run(self):
        pass
	
	# 定义call方法
    def __call__(self, *args, **kwargs):
        print('狗对象被执行了')

dog = Dog()
dog.run()
dog()

类装饰器装饰器执行对象

class Demo:
    def __init__(self,func):
    	# 初始化函数
    	# 创建对象时,会接收一个函数作为参数
        self.__func = func # 设置一个私有属性,指向了传入的函数

    def __call__(self, *args, **kwargs):
        print('添加功能')
        # 在call方法中调用传入的参数(函数)
        self.__func(*args,**kwargs)

@Demo #类装饰器
def add(a,b,c):
    print(a + b + c)

demo = Demo(add)
demo(5,6,7)

函数被多个装饰器装饰

执行结果遵循就近原则。

def makeBold(func):
    def wrapped():
        return "<b>" + func() + "<b>"

    return wrapped

def makeItalic(func):
    def wrapped():
        return "<i>" + func() + "<i>"

    return wrapped
@makeBold
@makeItalic
def set1():
    return 'helloworld'

print(set1())

拓展

for…else…

for i in range(10):
    print(i)
    if i>3:
        break
else:
    print('helloworld')

# for 循环 else结构   循环中如果有break 或contiue else不执行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值