闭包和装饰器

闭包是装饰器的前提

闭包可以保存函数内的变量,而不会随着调用完函数而被销毁

构成条件:

1,有函数嵌套

2,内函数使用外函数的参数

3,外函数将内函数返回出去

使用了外部函数的变量的内部函数称之为闭包

def func1(info):
  def func2(): # 函数嵌套
      print(info) # 内函数使用外函数的参数
  return func2 # 外函数将内函数返回出去

装饰器

在闭包的前提下,输入的是一个函数

def func1(f):
  def func2(): # 函数嵌套
      print('在函数前输出')
      f()
  return func2 # 外函数将内函数返回出去

nonlocal关键字:在嵌套函数中修改外部函数的变量

def func_out():
    a = 100
    def func_inner():
        nonlocal a
        a = a + 1
        print(f"修改的结果:{a}")
    return func_inner

number = func_out()
for i in range(5):
    number()

装饰器的两种表现形式:

表现一:传统表示

def check(fn):
    def inner():
        print('登录中...')
        fn()
    return inner

def comment():
    print('发布评论')

Comment=check(comment)
Comment()

表现二:语法糖

def check(fn):
    def inner():
        print('登录中...')
        fn()
    return inner

@check
def comment():
    print('发布评论')

comment()

无参无返回值

def func(f):
    def add_():
        print('正在计算中')
        f()
    return add_

@func
def get_sum():
    a=10
    b=20
    print(f'数字a + 数字b = {a+b}')

get_sum()

有参无返回值

def func(f):
    def inner(a,b):
        print('正在计算中')
        f(a,b)
    return inner

@func
def get_sum(a,b):
    print(f'数字a + 数字b = {a + b}')

get_sum(1,2)

无参有返回值

def func(f):
    def inner(a,b):
        print('正在计算中')
        res=f(a,b)
        return res
    return inner
@func
def get_sum(a,b):
    return a+b

print(get_sum(20,8))

有参有返回值

def func(f):
    def inner():
        print('正在计算中')
        res=f()
        return res
    return inner

@func
def get_sum():
    a=10
    b=20
    return a+b

print(get_sum())

多装饰器修饰一个函数

"""
发表评论前,都是需要 先登录用户 再进行 验证码验证。
先定义有发表评论的功能函数,然后在不改变原有函数的基础上,需要先检查用户登录和输入验证码。
"""
def func(f):
    def func2():
        print('检查登录')
        f()
    return func2

def funcy(f):
    def funcz():
        print('输入验证码')
        f()
    return funcz

@func
@funcy
def funcp():
    print('发表评论')

funcp()

在多装饰器修饰一个函数的时候,修饰顺序由上而下

带参数的修饰器

def logging(flag):
    def decorator(fn):
        def inner(num1,num2):
            if flag=='+':
                print("加法运算中")
            elif flag=='-':
                print('减法运算中')
            res=fn(num1,num2)
            return res
        return inner
    return decorator

@logging('+')
def add(num1,num2):
    res=num1+num2
    return res

@logging('-')
def reduce(num1,num2):
    res=num1-num2
    return res

rt=add(1,2)
print(rt)

装饰器外再包裹一个函数再由该函数接受参数并返回装饰器

深浅拷贝

可变类型:列表,字典,集合

余下均不可变

id关键字:查看变量的内存地址

1,深浅拷贝分别指的是

浅拷贝:copy模块的copy()

深拷贝:copy模块的deepcopy()函数

2,深拷贝拷贝的多,浅拷贝拷贝的少

3,深浅拷贝主要针对于可变类型拷贝来说,深拷贝拷贝所有层(可变),浅拷贝只拷贝第一层

如果是针对于不可变类型,则用法和普通赋值一样,并无区别