Python的深浅拷贝、闭包与装饰器

上一期文章给大家介绍了在Python语言中封装、继承和多态三大特征是如何实现的,感兴趣的伙伴可以前往阅读。本期文章主要介绍一下Python语言中深浅拷贝、闭包与装饰器相关的内容,闲言少叙,Let’s go!

一、深浅拷贝

1.1 可变类型和不可变类型

​ 在说深浅拷贝前先说两个概念——什么是可变类型?什么是不可变类型?记住一句话:在不改变地址值的情况下内容可以发生改变的类型为可变类型,反之为不可变类型。

常见数据类型分类如下:

# 可变类型:list、dict、set
# 不可变类型:int、float、str、tuple、bool

1.2 深浅拷贝

  • 深拷贝拷贝的多,浅拷贝拷贝的少。

  • 深浅拷贝都可以操作可变与不可变类型,但是多数操作可变类型

  • 浅拷贝使用copy模块的 copy()函数

  • 深拷贝使用copy模块的 deepcopy()函数

    代码如下(常做面试题):

    # 注意:在使用前先要导包
    import copy
    
    # 浅拷贝可变类型
    
    # 准备数据
    a = [1,2,3]
    b = [4,5,6]
    c = [a,b,7,8]
    d = copy.copy(c)
    # 操作
    a[0] = 11
    
    # 需求1.打印d
    print(d) 
    # 结果为
    [[11,2,3],[4,5,6],7,8]
    
    # 浅拷贝不可变类型
    
    # 准备数据
    aa = (1,2,3)
    bb = (4,5,6)
    cc = (aa,bb)
    
    # 操作
    dd = copy.copy(cc)
    # 需求1.打印dd
    print(cc)
    # 结果为
    ((1,2,3),(4,5,6))
    
    
    # 深拷贝可变类型
    
    # 准备数据
    aaa = [1,2,3]
    bbb = [4,5,6]
    ccc = [aaa,bbb,7,8]
    ddd = copy.deepcopy(ccc)
    # 需求1.打印ddd
    print(ddd) 
    # 结果为
    [[1,2,3],[4,5,6],7,8]
    
    # 操作
    aaa[1] = 222
    # 需求2.打印ccc
    print(ccc) 
    # 结果为
    [[1,222,3],[4,5,6],7,8]
    
    # 需求3.打印ddd
    print(ddd) 
    # 结果为
    [[1,2,3],[4,5,6],7,8]
    
    # 深拷贝不可变类型
    
    # 准备数据
    aaaa = (1,2,3)
    bbbb = (4,5,6)
    cccc = (aaaa,bbbb,7,8)
    
    # 操作
    dddd = copy.deepcopy(cccc)
    
    # 需求1.打印dddd
    print(dddd) 
    # 结果为
    ((1,2,3),(4,5,6),7,8)
    

二、闭包

闭包是python中的一种独特写法,可以延长函数局部变量的生命周期。要想形成闭包需满足以下三个条件:

  • 有嵌套:外部函数内要嵌套 内部函数。

  • 有引用:在内部函数中使用 外部函数的变量或者调用外部函数。

  • 有返回:在外部函数中, 返回 内部函数名, 即: 内部函数对象。

    代码如下:

    # 需求:创建一个闭包,实现统计函数执行的次数功能。
    
    # 定义记数函数
    def func_count():
        # 初始化计数器变量
        numCount = 0
    # 内部函数 打印内容 记录打印次数
        def fn_inner():             # 有嵌套
            print('hello world')
            # 授权 操作外部函数变量
            nonlocal numCount
            numCount += 1			# 有引用
            print(f'执行了{numCount}次')
    
        return fn_inner				# 有返回
    
    
    if __name__ == '__main__':
        # 调用
        f = func_count()
        f()
        f()
        f()
    

三、装饰器

​ 装饰器是闭包的一种,目的是在不改变原有函数的基础上, 对其功能做增强或者说扩展。

格式如下:

     	 def 外部函数名(形参列表):
            .....
            def 内部函数名(形参列表):         # 有嵌套
                功能扩展                    # 有额外功能
                ...
                使用外部函数的变量            # 有引用
            return 内部函数名               # 有返回

用法如下:

        方式1: 传统用法
            变量名 = 装饰器名(被装饰的函数名)
            变量名()

        方式2: 语法糖, @标记符实现
            在要被装饰的函数上,:  @装饰器名, 之后就跟普通调用函数方式一样, 该怎么调用就怎么调用。

代码如下:

# 定义函数充当装饰器
def check_login(fn_name):       # 外部函数 形参列表(固定写法必须有)
	 def fn_inner():			#内部函数  有嵌套
	    print('登录中...')		  # 有扩展(增强\额外功能)
		fn_name()				#有引用
	 return fn_inner			# 有返回

@check_login # 添加装饰器
# 定义原函数
def comment():
	print('发表评论...')
    
if __name__ == '__main__':
	# 1.普通写法
	# comment = check_login(comment)  # 装饰
	# comment()                  	  #调用
	
    # 语法糖写法
	comment()
    
    
    # 注意:装饰器的内置函数格式要和被装饰的函数(原函数)格式保持一致。
  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值