chap8-fluent python
浅拷贝 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的更多相关文章
- 学习笔记之Fluent Python
Fluent Python by Luciano Ramalho https://learning.oreilly.com/library/view/fluent-python/97814919462 ...
- 「Fluent Python」今年最佳技术书籍
Fluent Python 读书手记 Python数据模型:特殊方法用来给整个语言模型特殊使用,一致性体现.如:__len__, __getitem__ AOP: zope.inteface 列表推导 ...
- Fluent Python: memoryview
关于Python的memoryview内置类,搜索国内网站相关博客后发现对其解释都很简单, 我觉得学习一个新的知识点一般都要弄清楚两点: 1, 什么时候使用?(也就是能解决什么问题) 2,如何使用? ...
- Python深入学习之《Fluent Python》 Part 1
Python深入学习之<Fluent Python> Part 1 从上个周末开始看这本<流畅的蟒蛇>,技术是慢慢积累的,Python也是慢慢才能写得优雅(pythonic)的 ...
- Fluent Python: Classmethod vs Staticmethod
Fluent Python一书9.4节比较了 Classmethod 和 Staticmethod 两个装饰器的区别: 给出的结论是一个非常有用(Classmethod), 一个不太有用(Static ...
- Fluent Python: @property
Fluent Python 9.6节讲到hashable Class, 为了使Vector2d类可散列,有以下条件: (1)实现__hash__方法 (2)实现__eq__方法 (3)让Vector2 ...
- Fluent Python: Mutable Types as Parameter Defaults: Bad Idea
在Fluent Python一书第八章有一个示例,未看书以先很难理解这个示例运行的结果,我们先看结果,然后再分析问题原因: 定义了如下Bus类: class Bus: def __init__(sel ...
- 《Fluent Python》---一个关于memoryview例子的理解过程
近日,在阅读<Fluent Python>的第2.9.2节时,有一个关于内存视图的例子,当时看的一知半解,后来查了一些资料,现在总结一下,以备后续查询: 示例复述 添加了一些额外的代码,便 ...
- Fluent Python: Slice
Pyhton中序列类型支持切片功能,比如list: >>> numbers = [1, 2, 3, 4, 5] >>> numbers[1:3] [2, 3] tu ...
- fluent Python
1.1 Python风格的纸牌 Python collections模块中的内置模块:namedtuple https://www.liaoxuefeng.com/wiki/0013747381250 ...
随机推荐
- Java使用DOM方式读写XML
一.DOM读取 import ***; public class ReadXML { public static void main(String[] args) { try { //DOM Docu ...
- 解压命令tar zxvf中zxvf分别是什么意思
x : 从 tar 包中把文件提取出来z : 表示 tar 包是被 gzip 压缩过的,所以解压时需要用 gunzip 解压v : 显示详细信息f xxx.tar.gz : 指定被处理的文件是 xxx ...
- .NET 云原生架构师训练营(权限系统 RGCA 开发任务)--学习笔记
目录 目标 模块拆分 OPM 开发任务 目标 基于上一讲的模块划分做一个任务拆解,根据任务拆解实现功能 模块拆分 模块划分已经完成了边界的划分,边界内外职责清晰 OPM 根据模块拆分画出 OPM(Ob ...
- 纯JS脚本发送HTTP请求
1 var xmlHttp; 2 var iii = 0; 3 if (window.XMLHttpRequest) { 4 xmlHttp = new XMLHttpRequest(); 5 if ...
- SQLServer、Mysql、Oracle 创建、删除用户和授予用户权限
SQLServer 1.创建用户 CREATE LOGIN [用户名称] WITH PASSWORD='用户密码', DEFAULT_DATABASE=[默认数据库名称], CHECK_EXPIRAT ...
- MySQL架构原理之存储引擎InnoDB数据文件
MySQL架构原理之体系架构 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中简单介绍了MySQL的系统文件层,其中包含了数据文件.那么InnoDB的数据文件是如何分类并存储的呢? 一. ...
- 部署Zabbix 6.0 LTS
Blog:博客园 个人 本部署文档适用于CentOS 8.X/RHEL 8.X/Anolis OS 8.X/AlmaLinux 8.X. Zabbix 6.0 LTS于2022年2月15日发布,本次大 ...
- JAVA8学习——Stream底层的实现二(学习过程)
继续深入Stream的底层实现过程 2.spliterator() 接上 https://www.cnblogs.com/bigbaby/p/12159495.html 我们这次回到最开始源码分析的地 ...
- JVM内存结构的组成、各部分功能作用
一.程序计数器 作用:是记住下一条jvm指令的执行地址 特点: 是线程私有的 不会存在內存溢出 二.虚拟机栈 每个线程运行时所需要的内存,称为虚拟机栈 每个栈由多个栈帧(Frame) 组成,对应着 ...
- 微服务从代码到k8s部署应有尽有系列(七、支付服务)
我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...