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

简介: 原创如果有误请指出 今天看到python的列表深浅拷贝,不由得和C\C++进行了比较如下: 其实python中的深COPY和浅COPY和C\C++中是一样的,毕竟python底层是C/C++做的,这方面保留了 C\C++的原理,对于类或者结构体复制构造函数等号(=)操作符保留了浅COPY,当然我们可以自定义 这些函数。

原创如果有误请指出

今天看到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
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
微信.jpg
相关文章
|
4月前
|
算法框架/工具 C++ Python
根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现
根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现
304 0
|
5月前
|
编译器 开发工具 C++
【Python】已解决error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build
【Python】已解决error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build
2907 0
|
2月前
|
C++ Python
探索Python与C/C++混合编程的艺术
探索Python与C/C++混合编程的艺术
50 1
WK
|
3月前
|
机器学习/深度学习 Java 程序员
为什么Python比C++慢很多?
Python相较于C++较慢主要体现在:动态类型系统导致运行时需解析类型,增加开销;作为解释型语言,逐行转换字节码的过程延长了执行时间;自动内存管理和垃圾回收机制虽简化操作但也带来了额外负担;全局解释器锁(GIL)限制了多线程性能;尽管Python库方便灵活,但在性能上往往不及C++底层库。然而,Python在某些领域如数据分析、机器学习中,凭借其高级别抽象和简洁语法仍表现出色。选语言需依据具体应用场景和需求综合考量。
WK
90 1
|
4月前
|
Unix C语言 C++
Python调用C/C++
Python调用C/C++
28 2
|
4月前
|
PHP C++ Python
右手坐标系,空间点绕轴旋转公式&程序(Python和C++程序)
右手坐标系,空间点绕轴旋转公式&程序(Python和C++程序)
82 0
WK
|
4月前
|
机器学习/深度学习 运维 Java
Python 相对于 C++ 有哪些明显的优势
C++是一种强大且高效的编程语言,被广泛应用在系统软件、游戏开发、嵌入式系统等多个领域。然而Python在某些方面展现出显著优势:Python语法简洁直观,易于学习与使用,提高了代码的可读性和团队协作效率;拥有丰富的第三方库和框架资源,能有效提升开发效率;具备良好的跨平台性,无需大量修改即可适应不同操作系统;
WK
64 0
|
5月前
|
算法 Java C++
C++和Python在内存管理上的主要区别是什么?
【7月更文挑战第2天】C++和Python在内存管理上的主要区别是什么?
130 1
|
5月前
|
存储 Java 程序员
Python和C++在内存管理方面有什么不同?
【7月更文挑战第2天】Python和C++在内存管理方面有什么不同?
95 0
|
5月前
|
Java C++ 开发者
如何根据项目需求选择使用C++还是Python进行内存管理?
【7月更文挑战第2天】如何根据项目需求选择使用C++还是Python进行内存管理?
48 0