今天写程序,人为制造了一个由浅拷贝引起的bug,有必要归纳一下。先附上源代码: class PerformanceTest(object):
def __init__(self):
.......
self.basic_path_list=[]
....... #这就是一个生成基础路径名的函数,从26个字符中选择五个字符加上‘/'构成基础路径
def _get_basic_path_list(self,path_num):
.......
self.basic_path_list.append(path)
....... .......
#这是一个对用Elementtree实现的xml树进行测试的测试函数,首先需要的就是生成测试路径列表
#建立一颗结点数目为test_num,满child_num叉树
def add_performance_test(self,child_num,test_num):
.......
#mid_list=deepcopy(self.basic_path_list)
#path_list=deepcopy(self.basic_path_list)
mid_list=self.basic_path_list
path_list=self.basic_path_list
while len(path_list)<test_num:
child_list=[]
for mid_path in mid_list:
for spath in self.basic_path_list:
path=mid_path+spath
child_list.append(path) if len(path_list)+len(child_list)>test_num:
path_list+=child_list[:test_num-len(path_list)]
break
else:
path_list+=child_list mid_list=child_list #接下来就是将path_list中所有元素添加到自己定义的xml树中,代码略
......
 
    结果,我在执行add_performance_test(2,100)函数后发现,生成的xml文件中目录树居然有9层。
    100=1+2+4+8+16+32+37,应该是7层,却生成了9层目录,bug在哪里? 
    经过一段时间的调试后,确信是self.basic_path_list值在执行过程中起了变化,这是绝对不应该的。后来回想起初学python时看到的关于浅拷贝和深拷贝的内容,恍然大悟。mid_list和path_list在赋值的时候均执行的是浅拷贝,path_list在循环中改变时,也改变了self.basic_path_list值。 找到了问题,在赋值时将浅拷贝替换为深拷贝,代码就正常运行了。
 

这个错误给我敲响了警钟,像这样的bug代码不会报错,但根本得不到需要的结果。我仔细检查了以前写的代码,还发现了几处类似的浅拷贝,尤其是运行那些代码可以得要预期结果,但为了保险起见,我还是将其均替换为深拷贝。

在最后摘录一部分python核心编程中对于浅拷贝和深拷贝的描述,望以后写程序时引以为戒。

序列类型的可以通过三种方式实现浅拷贝,浅拷贝也是默认的拷贝类型:(1)完全切片操作;(2)利用工厂函数,比如list()等;(3)使用copy模块中的copy()函数。然而对于非容器类型没有拷贝这这一说。

有几点关于拷贝操作的警告。第一,非容器类型(比如数字,字符串和其他"原子"类型的对象,像代码,类型和xrange对象等)没有深拷贝一说,浅拷贝是用完全切片操作来完成的.第二,如果元组变量只包含原子类型对象,对它的深拷贝将不会进行.

python浅拷贝与深拷贝的更多相关文章

  1. python 浅拷贝和深拷贝(9)

    何谓浅拷贝/深拷贝,说得直白一点,其实就是数据拷贝,两者到底有什么区别呢?听着就挺迷糊的,python开发项目的时候说不定你就能碰上这样的坑~~     一.普通的变量赋值 我们平常使用的变量赋值就是 ...

  2. python浅拷贝和深拷贝

    博文参考地址:https://blog.csdn.net/qq_20084101/article/details/82925067 最近在撸码的时候发现了一个严重的问题: a = [1,2] c = ...

  3. Python浅拷贝与深拷贝(可变对象与不可变对象)

    第一次遇到深拷贝和浅拷贝的问题是用python在一个for循环中对一个list赋值,使用的语句是 a = b 这个b会不断带入循环,每次计算得到,最后发现list乱七八糟的,后来才发现,python中 ...

  4. python浅拷贝与深拷贝浅析

    首先我们要明确,python中大多数都是浅拷贝,我们先说原因: 1.时间花费更少 2.内存更小 3.效率更高,浅拷贝只拷贝顶层数据,一般情况下比深拷贝效率高. 容器(如列表)切片是浅拷贝

  5. 学习Python一年,这次终于弄懂了浅拷贝和深拷贝

    官方文档:copy主题 源代码: Lib/copy.py 话说,网上已经有很多关于Python浅拷贝和深拷贝的文章了,不过好多文章看起来还是决定似懂非懂,所以决定用自己的理解来写出这样一篇文章. 当别 ...

  6. 【转】Python中的赋值、浅拷贝、深拷贝介绍

    这篇文章主要介绍了Python中的赋值.浅拷贝.深拷贝介绍,Python中也分为简单赋值.浅拷贝.深拷贝这几种"拷贝"方式,需要的朋友可以参考下   和很多语言一样,Python中 ...

  7. 关于python中赋值、浅拷贝、深拷贝之间区别的深入分析

    当重新学习了计算机基础课程<数据结构和算法分析>后再来看这篇自己以前写的博文,发现错误百出.python内置数据类型之所以会有这些特性,归根结底是它采用的是传递内存地址的方式,而不是传递真 ...

  8. python中的深拷贝与浅拷贝

    深拷贝和浅拷贝 浅拷贝的时候,修改原来的对象,浅拷贝的对象不会发生改变. 1.对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷 ...

  9. python的浅拷贝和深拷贝

    python对象有两种拷贝的形式:浅拷贝和深拷贝. 在<python核心编程>中看到对这两种拷贝的分析,觉得十分收益,所以记录在此. id()方法:id()方法可以查看某个对象的ID,类似 ...

随机推荐

  1. Django day25 序列化组件(*****)

    序列化:将变量从内存中存储或传输的过程称之为序列化 1.序列化组件是干什么用的? 对应着表,写序列化的类 2.如何使用序列化组件 Serializer 1) 重命名:用source:xx = seri ...

  2. jdk1.8 api 下载

    链接: https://pan.baidu.com/s/1Wmf2vzXxclVcBPUfPp_g_A 提取码: dpwu 希望那些CSDN的不要借此収积分,行行好吧你,小众程序员就是为了方便 凑字数 ...

  3. mysql中判断记录是否存在方法

    以下这个方法是我推荐的. sql语句:select 1 from tablename where col = col limit 1; 然后读取语句执行所影响的行数. 当然这里limit 1很重要.这 ...

  4. 题解报告:hdu 1527 取石子游戏(威佐夫博弈)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1527 Problem Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石 ...

  5. viewDidUnload,viewDidLoad,viewWillAppear,viewWillDisappear的作用以及区别

    viewDidLoad:在视图加载后被调用 viewWillAppear:视图即将可见时调用.默认情况下不执行任何操作 viewDidAppear: 视图已完全过渡到屏幕上时调用 viewWillDi ...

  6. 【转】Linux账号管理之useradd

    转自:http://www.jb51.net/article/45848.htm Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然 ...

  7. Unity学习-工具准备(一)

    工具介绍 Unity 4.5.4 VS2013 Visual Studio 2013 Tools for Unity unity3d圣典 五大面板 Hierarchy:场景资源面板 [管理 当前场景 ...

  8. kubernetes installing and using 单机版

    centos安装docker uname -r yum remove docker \ docker-client \ docker-client-latest \ docker-common \ d ...

  9. Python随笔-函数

    在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回. def GetMax(v1, v2):#注 ...

  10. JVM 内存区域划分

    一.运行时数据区包括哪几部分? 根据<Java虚拟机规范>的规定,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register).Java栈(VM Stac ...