浅拷贝 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. 关于linux shell编程,alias rm='cp $@ ~/backup; rm $@'

    书上的这个例子需要在ubuntu的低版本的系统才支持,现在基本上都不支持了,想实现也很简单自己写一个脚本先备份再删除. alias也只是做了一次替换alias rm='cp $@ ~/backup; ...

  2. ACM-ICPC 2015辽宁省赛

    省赛之于ACM 就是让省内的队伍互相比较而已~~~(何况弱省(本渣校  四个二等四个三等(其实是六个三道题 两个两道题,是院长后来和主办方沟通了下- - (本弱很水,但还是要吐槽:好水的省赛啊!!

  3. DHCP原理与LINUX下的配置

    DHCP原理与LINUX下的配置 目录 DHCP原理与LINUX下的配置 一.DHCP工作原理 1.DHCP概述 2.DHCP的优势 3.DHCP的分配方式 (1)自动分配 (2)手动分配 (3)动态 ...

  4. 关于单调性优化DP算法的理解

    Part1-二分栈优化DP 引入 二分栈主要用来优化满足决策单调性的DP转移式. 即我们设\(P[i]\)为\(i\)的决策点位置,那么\(P[i]\)满足单调递增的性质的DP. 由于在这种DP中,满 ...

  5. 【CF712E】Memory and Casinos(数学 期望 DP)

    题目链接 大意 给出一个序列,当你在某个点时,有一个向右走的概率\(P_i\)(向左为\(1-P_i\)), 给出\(M\)个操作,操作有两类: 1 X Y Z:把\(P_X\)的值修改为\(\fra ...

  6. JDBC加强

    一.使用PreparedStatement预编译语句防止SQL注入 什么是SQL注入? 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行 ...

  7. 正则表达式以及re模块的使用

    内容概要 正则表达式简介 字符组 特殊符号 量词 贪婪匹配与非贪婪匹配 取消转义 正则表达式简介 '''正则表达式是一门语言,如果想在python中使用,需要导入re模块''' # 什么是正则表达式? ...

  8. 关于c#知识的学到的新知识点

    开头:对这段时间学习的小知识点做一个整理.希望自己能理清思路.当然如果能帮到大家那就更好了. 1.判断写法 !True=false 思考:以前判断一直写if(布尔变量==false),今天看到这个,才 ...

  9. TestNG基本使用

    TestNG简介 Testng是一套开源测试框架,是从Junit继承而来,testng意为test next generation 创建maven项目,添加依赖 <dependency> ...

  10. [转自Matrix67] 趣题:顶点数为多少的图有可能和自己互补

    若干个顶点以及某些顶点和顶点之间的连线,就构成了一个"图".如果对某个图进行变换,使得原来任意两个有连线的顶点之间都不再有连线,原来任意两个没有连线的顶点之间现在都有连线了,那么所 ...