从C C++的角度看PYTHON的深浅拷贝

原创如果有误请指出

今天看到python的列表深浅拷贝,不由得和C\C++进行了比较如下:

其实python中的深COPY和浅COPY和C\C++中是一样的,毕竟python底层是C/C++做的,这方面保留了
C\C++的原理,对于类或者结构体复制构造函数等号(=)操作符保留了浅COPY,当然我们可以自定义
这些函数。我们先从C++的简单的复制构造函数等号(=)操作符的例子开始

#include<iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;

class testcy
{

        private:
                char* a;
                unsigned int b;
        public:
                testcy(const char* inc)
                {

                        a = new char[strlen(inc)+1];
                        strcpy(a,inc);
                        b = 1;
                }
                testcy()
                {

                        a= NULL;
                        b = 0;
                }
                testcy(const testcy &in) //浅copy 构造函数
                {

                        this->a = in.a;
                        this->b = in.b;
                }
                testcy& operator=(const testcy& in)//浅=值操作符重载
                {

                        this->a = in.a;
                        this->b = in.b;
                }

                void print()
                {

                        cout<<this->a<<"   ";
                        cout<<this->b<<endl;
                }

                void modify(const char* in,const int in2)
                {

                        if(strlen(a) < strlen(in))
                        {

                                cout<< "error:much lenth than point a char"<<endl;
                                exit(1);
                        }
                        else
                        {

                                for(int i=0;i<strlen(in);i++)
                                {

                                        *(a+i) = *(in+i);
                                }
                        }
                        b = in2;

                }

};

int main(void)
{

        testcy a("123123");
        testcy b = a;
        testcy c ;
        c = a;
    cout<<"source data:"<<endl;
        cout<<"string  int"<<endl;
        a.print();
        b.print();
        c.print();

        cout<<"after only change a:"<<endl;
        cout<<"string  int"<<endl;
        a.modify("asd",2);

        a.print();
        b.print();
        c.print();

} 

非常简单就是为了演示浅COPY输出如下:

source data:
string  int
123123   1
123123   1
123123   1
after only change a:
string  int
asd123   2
asd123   1
asd123   1 

我们可以看到在修改a的数据后b、c的数据string数据也更改了,但是简单类型int没有更改。那么我们用内存四区图来描述

123.jpg

图中a->a当然就是整形,但是a->b是指针其指针的值0XB0120存在栈中但是实际指向的数据存在堆中,
而变量b->b,c->b指向了同一块内存 导致一改全部都改了,但是a->a,b->a,c->a确实单独的在栈上了的
没影响。其实这里我们只要修改浅COPY为深COPY改变其实现即可比如

 testcy(const testcy &in) //深copy 构造函数
        {

            this->a = new char[strlen(in.a)+1];
            strcpy(this->a,in.a);
            this->b = in.b;
        } 

我们要做的不仅仅是要指针相等而是要将内存重新分配。注意本测试程序没有写析构函数。

下面我们来看看python的浅列表拷贝

import copy              

a = ['t1','t2','t3','t4']
b = a
print("source data")
print(a);
print(b);                

a[0] = 'gao'
print("after change:")   

print(a);
print(b); 
source data
['t1', 't2', 't3', 't4']
['t1', 't2', 't3', 't4']
after change:
['gao', 't2', 't3', 't4']
['gao', 't2', 't3', 't4'] 

确实如此,修改了列表元素a[0]的值b列表也修改了,我们有了C++的那张图这个就很好理解了,他们是
指向同一块内存堆区。我们应该使用

a = ['t1','t2','t3','t4']
b = copy.deepcopy(a) 

从这个方法的命名我们也可以看到这是深copy,其原理已经在C++代码进行了剖析
另外如下:

a = [['t1','t10'],'t2','t3','t4']
b = a.copy()                          

print("source data")
print(a);
print(b);                        

a[0][0] = 'gao'
print("after change:")           

print(a);
print(b); 
source data
[['t1', 't10'], 't2', 't3', 't4']
[['t1', 't10'], 't2', 't3', 't4']
after change:
[['gao', 't10'], 't2', 't3', 't4']
[['gao', 't10'], 't2', 't3', 't4'] 

a.copy()只是对第一层进行copy,第二层在python里面实现应该也是指针或者引用,一样的会出问题。
所以copy的时候我们尽量使用copy.deepcopy(a)来得到正确的数据当然根据实际需求定。
可以看到C/C++是理论基础,有了这些理论PYTHON中的很多现象很好理解。

作者微信:

微信.jpg

时间: 2024-10-31 21:31:36

从C C++的角度看PYTHON的深浅拷贝的相关文章

从脚本编程的角度看JSP的安全

JSP作为建立动态网页的技术正在不断升温.JSP和ASP.PHP.工作机制不太一样.一般说来,JSP页面在执行时是编译式,而不是解释式的.首次调用JSP文件其实是执行一个编译为Servlet的过程.当浏览器向服务器请求这一个JSP文件的时候,服务器将检查自上次编译后JSP文件是否有改变,如果没有改变,就直接执行Servlet,而不用再重新编译,这样,效率便得到了明显提高. 今天我将和大家一起从脚本编程的角度看JSP的安全,那些诸如源码暴露类的安全隐患就不在这篇文章讨论范围之内了.写这篇文章的主要

从三个角度看上海园区招募网

由于没有实际了解asus生产流程及hr部门,所以以下分析仅从网络专业角度来看上海园区招募网,未能结合asus实际提出改进建议和发展目标(比如可以把上海园区招募网独立出来发展成电子行业的专业招聘网,一方面来服务asus另外也可以带来实际的收益.)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 一.从网站设计技术角度看上海园区招募网 1.上海园区招募网最好有自己独立的域名

王顺铨:站在消费者角度看互联网

主持人:首先给我们介绍一下您的个人经历,包括您这次参赛的网站. 王顺铨:因为我是学艺术类的,是中央工艺美院毕业的,一直做广告搞平面设计.在2005年开始进入互联网,在2006年通过自己的特长和专长,建了一个音乐网站,因为自己对音乐比较喜欢.当时发现互联网上高品质,高端的音乐比较少,当时就进入高端市场.现在百度搜索网络音乐相对来说比较,他的质量都比较低,对于拿高端MP3播放器的人就比较枯燥,我们就解决他这个问题.现在随着播放器空间的放大,他可以储存很大容量的文件,我们高品质音乐的网站,就是现阶段满

从多元化的角度看seo 才能真正落实站点的优化

  SEO现在进入了蓬勃发展的时期,上到大型站点,下到草根站长,越来越多的人都对SEO给予了足够的重视以及期望,希望靠着这个后起之秀让自己的站点在竞争激烈的网络时代,获得更多的优势.近期笔者参加了夫唯的培训,培训后不能说自己已经掌握所有的SEO优化技巧,但是最基本的什么该做,什么不该做还是有一定的分辨能力的.当大多数的人都认为优化其实是由内容和外链的建设模式,笔者认为大家的想法太局限了,从优化的操作上来看,一个站点的优化的确是建立在内容和外链,但SEO显然没有你所想的那样"低技术",一

从百度角度看SEO与UEO的关系

SEO即搜索引擎优化,UEO即User Experience Optimization的缩写,即用户体验优化,这两者到底有什么关系呢?笔者根据自己5年的SEO行业经验,谈一下自己的看法.站在百度角度看,在网站优化中,SEO只是手段之一,UEO是目的,UEO的目标即网站最佳化. 1.SEO只是网站优化手段 SEO为站长朋友所熟知,在这里不做过多解释.笔者在5年的SEO经历中,发现有的站长朋友过分依赖SEO,笔者认为SEO只是网站优化的一种手段,而网站优化只是网站运营的一个过程.过度SEO被百度惩罚

从开发者角度看国内Android Market的用户体验

开发者角度看国内Android Market的用户体验-小程序 体验者 开发者"> 编者按:本文作者为丁香园CTO,贝塔咖啡联合创始人,冯大辉 近一段时间在发布 丁香园用药助手 Android 版的过程中把国内几个重要的 Android Market 用了个遍,每次要发布新版本的时候都要感慨一下:几乎所有的 Android Market 后台的用户体验都不怎么好. 信息各有一 国内所有的 Android Market 和 Google 官方 Android Market 都是不"

王胜航:从实践角度看云计算助企业转型

本文讲的是王胜航:从实践角度看云计算助企业转型,2012年5月23-25日,主题为"发挥示范引领作用,推动云计算创新实践"的"第四届中国云计算大会"在北京国家会议中心召开.大会将举办七个专题论坛,围绕云计算核心技术架构.云计算与大数据.云计算平台与应用实践.云计算时代的信息安全.云计算数据中心.云计算存储与虚拟化.云计算与移动互联网及新型终端等主题进行深入探讨.IT168会进行直播报道. ▲IBM大中华区云计算事业部总经理 王胜航 云计算不仅仅是技术,而是商业模式的

从JDK源码角度看Float

关于IEEE 754 在看Float前需要先了解IEEE 754标准,该标准定义了浮点数的格式还有一些特殊值,它规定了计算机中二进制与十进制浮点数转换的格式及方法.规定了四种表示浮点数值的方法,单精确度(32位).双精确度(64位).延伸单精确度(43位以上)与延伸双精确度(79位以上).多数编程语言支持单精确度和双精确度,这里讨论的Float就是Java的单精确度的实现. 浮点数的表示 浮点数由三部分组成,如下图,符号位s.指数e和尾数f. 对于求值我们是有一个公式对应的,根据该公式来看会更简

从JDK源码角度看Byte

Java的Byte类主要的作用就是对基本类型byte进行封装,提供了一些处理byte类型的方法,比如byte到String类型的转换方法或String类型到byte类型的转换方法,当然也包含与其他类型之间的转换方法. 主要实现代码如下: public final class Byte extends Number implements Comparable<Byte> { public static final byte MIN_VALUE = -128; public static fina