浅拷贝 VS 深拷贝

# In[]
# list 生成一个新的引用对象,只是用alst完成初始化
alst = [1,2,3,4,5]
blst=list(alst)
alst.append(6)
print(blst) # In[]
alst = [1,2,3,4,5]
blst=alst # 浅拷贝,两者同时变化
alst.append(6)
print(blst) # In[]
from copy import copy alst = [1,2,3,4,5]
blst=alst.copy() # 浅拷贝,两者同时变化
alst.append(6)
print(blst) # In[]
import copy
alst = [1,2,3,4,5]
blst=copy.deepcopy(alst) # 深拷贝,可以认为是用alst初始化一个新的对象
alst.append(6)
print(blst)

此处,对可变类型而言,深拷贝其实就是创建了一个新的引用对象,可以认为原来的只是用来做初始化用的。新旧有变化对彼此都没有影响了。浅拷贝可以认为就是起了个别名。

由于这层原因,当可变类型作为函数参数时,尤其要谨慎处理。首先考虑初始化,如果存在None,该怎么处理,其次如果你不想修改传入参数的值,那么要给类或者函数的属性创建一个副本或者说只是拿传入的参数作为初始化,务必保证,函数内部修改可变类型变量时,形参传入的变量不会受到影响。

'''
the default value of paramter is None
'''
import copy
# tag::BUS_CLASS[]
class Bus: def __init__(self, passengers=None):
if passengers is None:
self.passengers = []
else:
self.passengers = list(passengers) def pick(self, name):
self.passengers.append(name) def drop(self, name):
self.passengers.remove(name)
# end::BUS_CLASS[] bus1 = Bus(['a','b','c'])
bus2 = copy.copy(bus1)
bus1.pick('d')
bus1.drop('a')
print(bus2.passengers)
bus3= copy.deepcopy(bus1)
print(bus3.passengers)
bus1.pick('a')
bus1.drop('d')
print(bus3.passengers)
print(bus1.passengers)

  

此时如果对默认参数处理不好,会引起很诡异的事情。但是如果用list生成一个新的对象,就会避免这个问题。

'''
Mutable Types as Parameter Defaults:Bad Idea
''' # tag::HAUNTED_BUS_CLASS[]
class HauntedBus:
"""A bus model haunted by ghost passengers""" def __init__(self, passengers=[]): # <1>
# should be list function to initialization the attribute
self.passengers = passengers #list(passengers) # <2> def pick(self, name):
self.passengers.append(name) # <3> def drop(self, name):
self.passengers.remove(name)
# end::HAUNTED_BUS_CLASS[] bus1 = HauntedBus(['Alice', 'Bill'])
print(bus1.passengers)
bus1.pick('Charlie')
bus1.drop('Alice')
print(bus1.passengers) bus2 = HauntedBus()
bus2.pick('Carrie')
print('bus2.passengers:',bus2.passengers) bus3 = HauntedBus()
print('bus3.passengers:',bus3.passengers)
bus3.pick('Dave')
print('bus3.passengers:',bus3.passengers)
print(bus2.passengers is bus3.passengers)
print('bus1.passengers:',bus1.passengers)

  

还有,这个程序,把形参改变了,本来不该改变的。

'''
here the attribute passengers should be initialized using a list func. ''' # tag::TWILIGHT_BUS_CLASS[]
class TwilightBus:
"""A bus model that makes passengers vanish""" def __init__(self, passengers=None):
if passengers is None:
self.passengers = [] # <1>
else:
# this can change the passengers when you change self.passengers
self.passengers = passengers #<2> def pick(self, name):
self.passengers.append(name) def drop(self, name):
self.passengers.remove(name) # <3>
# end::TWILIGHT_BUS_CLASS[] basketball_team = ['Sue', 'Tina', 'Maya', 'Diana', 'Pat']
bus = TwilightBus(basketball_team)
bus.drop('Tina')
bus.drop('Pat')
print(basketball_team)

  

这几个程序大家都看到了,其实很关键的一个地方是list函数的使用。test =  list(alst)相当于将alst 进行深拷贝,改变alst时,test不会随之改变,改变test时,alst也不会有影响。也可以理解为将alst作为参数,对元素追个转换,生成一个新的list并返回给test。因此,两者之间不再有影响。

chap8-fluent python的更多相关文章

  1. 学习笔记之Fluent Python

    Fluent Python by Luciano Ramalho https://learning.oreilly.com/library/view/fluent-python/97814919462 ...

  2. 「Fluent Python」今年最佳技术书籍

    Fluent Python 读书手记 Python数据模型:特殊方法用来给整个语言模型特殊使用,一致性体现.如:__len__, __getitem__ AOP: zope.inteface 列表推导 ...

  3. Fluent Python: memoryview

    关于Python的memoryview内置类,搜索国内网站相关博客后发现对其解释都很简单, 我觉得学习一个新的知识点一般都要弄清楚两点: 1, 什么时候使用?(也就是能解决什么问题) 2,如何使用? ...

  4. Python深入学习之《Fluent Python》 Part 1

    Python深入学习之<Fluent Python> Part 1 从上个周末开始看这本<流畅的蟒蛇>,技术是慢慢积累的,Python也是慢慢才能写得优雅(pythonic)的 ...

  5. Fluent Python: Classmethod vs Staticmethod

    Fluent Python一书9.4节比较了 Classmethod 和 Staticmethod 两个装饰器的区别: 给出的结论是一个非常有用(Classmethod), 一个不太有用(Static ...

  6. Fluent Python: @property

    Fluent Python 9.6节讲到hashable Class, 为了使Vector2d类可散列,有以下条件: (1)实现__hash__方法 (2)实现__eq__方法 (3)让Vector2 ...

  7. Fluent Python: Mutable Types as Parameter Defaults: Bad Idea

    在Fluent Python一书第八章有一个示例,未看书以先很难理解这个示例运行的结果,我们先看结果,然后再分析问题原因: 定义了如下Bus类: class Bus: def __init__(sel ...

  8. 《Fluent Python》---一个关于memoryview例子的理解过程

    近日,在阅读<Fluent Python>的第2.9.2节时,有一个关于内存视图的例子,当时看的一知半解,后来查了一些资料,现在总结一下,以备后续查询: 示例复述 添加了一些额外的代码,便 ...

  9. Fluent Python: Slice

    Pyhton中序列类型支持切片功能,比如list: >>> numbers = [1, 2, 3, 4, 5] >>> numbers[1:3] [2, 3] tu ...

  10. fluent Python

    1.1 Python风格的纸牌 Python collections模块中的内置模块:namedtuple https://www.liaoxuefeng.com/wiki/0013747381250 ...

随机推荐

  1. 浅谈Java中重写与重载的区别

    重载和重写是Java中两个截然不同的概念.但是却因为名字相近导致很多人经常混淆. 下面用例子展示出他们之间的区别. 在Java中,重载(overloading) 发生在本类.方法名相同,参数列表不同, ...

  2. apt安装zabbix

    下面介绍基于ubuntu18.04,使用apt在ubuntu安装zabbix 4.0.x版本.规划在10.0.0.101主机安装zabbix server,在10.0.0.104安装提供msyql服务 ...

  3. elasticsearch按URL查询

    排序查询:localhost:9200/get-together/_search?sort=date:asc, 排序以及按字段查询:localhost:9200/get-together/_searc ...

  4. 基于GDAL库海洋表温日平均计算工具设计与实现 C++版

    技术背景 在对物理海洋数据处理过程中,表层温度是众多要素中的一种,本文书要是针对海洋表温数据批量日平均处理的一个工具设计.首先要在对当前的SST数据文件作一下简要的说明,SST全称为sea surfe ...

  5. Solution -「ZJOI 2020」「洛谷 P6631」序列

    \(\mathcal{Description}\)   Link.   给定一个长为 \(n\) 的非负整数序列 \(\lang a_n\rang\),你可以进行如下操作: 取 \([l,r]\),将 ...

  6. Unreal ListView使用篇

    应用 ListView,在Unreal UI界面开发中用途非常广泛,基本只要你使用列表,就得需要用ListView.比如排行榜100个列表,界面上只需要显示出10个,我们肯定不能生成100个ui实例, ...

  7. Python基础—内置函数(Day14)

    一.内置函数 1.***eval:执行字符串类型的代码,并返回最终结果(去掉括号里面是什么就返回什么). print(eval('3+4')) #7 ret = eval('{"name&q ...

  8. Dubbo基础三之配置方式简述

    Dubbo基础一之实战初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中,体验了两种配置方式一种注解一种xml.其中xml是在注解配置失败没有找到解决方法后选择xml替代体验的.那 ...

  9. ios cannot use "@throw" with objective-c exceptions disabled 问题解决方案

    http://blog.csdn.net/huayu_huayu/article/details/51781182 我不转载  我跳转 哈哈哈哈哈哈   其实也就是 解决办法:修改target -&g ...

  10. 关于 Xcode 更新 appleID 更换

    可能不少人会遇到 前一位同事走之后,他的 appID帐号下载的东西更新不了 下面给予大家一个解决办法  例如 Xcode  1.打开引用程序目录 2.找到Xcode,右键"显示包内容&quo ...