1. 首页
  2. IT资讯

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

原创如果有误请指出

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

其实python中的深COPY和浅COPY和CC++中是一样的,毕竟python底层是C/C++做的,这方面保留了
CC++的原理,对于类或者结构体复制构造函数等号(=)操作符保留了浅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

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

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7728585/viewspace-2144168/,如需转载,请注明出处,否则将追究法律责任。

主题测试文章,只做测试使用。发布者:深沉的少年,转转请注明出处:http://www.cxybcw.com/183893.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code