python的深浅拷贝与linux中的软硬链接 - Go语言中文社区

python的深浅拷贝与linux中的软硬链接


放在开头

       在学习linux中的软硬链接时,总是无法理解两者之间的区别,为什么创建软链接或者硬链接之后修改其中一个的内容另外一个会随着改变?两者的区别在哪里呢?
       后来发现凭借自己硬想根本理解不了,上网搜索了之后也不能理解的太好,果然还是依靠画图的方式来理解才能基本掌握。
        后来在学习了python中的深浅拷贝后,突然发现和linux中的软硬链接的概念挺像的,但是后来仔细体会并上机实验,算是稍稍理解里面的区别。在这里就记录一篇博客说说我自己的理解,在以后忘记的时候回来看一看。

软硬连接

话不多说,先上图
软硬链接示意图
我觉得这张图片已经能够很好地反映软硬连接之间的区别了。学过C语言或者linux系统的都应该知道指针的存在,linux中的文件内容与名字之间的关系就如图所示,文件名和文件的数据 是分开存储的,由一个文件名指向文件数据的开始位置(这是它们逻辑上的一个关系,实际上文件名中储存的是文件数据开始位置的地址等信息,这样才能找到文件数据)。
创建软连接的命令为:

ln -s 被链接的源文件(要建立链接的完整路径) 链接文件(链接名)

       建立文件的软连接,用通俗的方式讲类似于Windows 下的快捷方式。查看一下快捷方式的属性,可以看到快捷方式中存储的就是文件的完整路径,而并非文件本身。

  • 注意
  1. 没有 -s 选项建立的是一个 硬链接文件,两个文件占用相同大小的硬盘空间,工作中几乎不会建立文件的硬链接
  2. 源文件要使用 绝对路径 ,不要使用相对路径,这样可以方便移动链接文件后,仍然能够正常使用。
  • 提示:

    • 在Linux 中,只有文件的 硬链接数 == 0 才会被删除
    • 使用 ls -l 可以查看一个文件的硬链接的数量
    • 在日常工作中,几乎不会创建文件的硬链接,知道即可(即使在同一个文件夹中建立的也是软连接而不是硬链接)
  • 特别说明:

       软链接实际上只是一段文字,里面包含着它所指向的文件的名字,系统看到软链接后自动跳到对应的文件位置处进行处理;相反,硬联接为文件开设一个新的目录 项,硬链接与文件原有的名字是平权的,在Linux看来它们是等价的。由于这个原因,硬链接不能连接两个不同文件系统上的文件。
(1)软连接可以 跨文件系统 ,硬连接不可以 。实践的方法就是用共享文件把windows下的 aa.txt文本文档连接到linux下/root目录 下 bb,cc . ln -s aa.txt /root/bb 连接成功 。ln aa.txt /root/bb 失败 。
(2)硬连接不管有多少个,都指向的是同一个I节点,会把 结点连接数增加,只要结点的连接数不是 0,文件就一直存在,不管你删除的是源文件还是 连接的文件 。只要有一个存在 ,文件就 存在 (其实也不分什么源文件连接文件的 ,因为他们指向都是同一个 I节点)。 当你修改源文件或者连接文件任何一个的时候 ,其他的文件都会做同步的修改。软链接不直接使用节点号作为文件指针,而是使用文件路径名作为指针。所以 删除连接文件 对源文件无影响,但是删除源文件,连接文件就会找不到要指向的文件 。软链接有自己的inode,并在磁盘上有一小片空间存放路径名.
(3)软连接可以对一个不存在的文件名进行连接 。
(4)软连接可以对目录进行连接。

python中对象的深浅拷贝

        如果能够理解了linux中的软硬链接,那么对于python中深浅拷贝的理解就能够相对容易些,结合上面的图片理解将会理解的更加透彻。
这篇
博客中讲的已经很全面了,我就不再列举例子了,只是讲讲自己的理解。

浅拷贝

        python中的浅拷贝,也就是使用赋值号(=)创建的新对象就属于浅拷贝,浅拷贝与linux中的硬连接非常相似,通俗地讲就是:拷贝了引用,并没有拷贝内容。但是浅拷贝与硬链接的一点区别就是修改(指的是对变量进行赋值操作)其中一个变量的值,另一个变量的值不会改变,因为修改变量的值改的是变量的引用而不是变量所指向内存的内容,如图一所示
浅拷贝图示
       对b进行append操作时如图二所示,对a或者b进行append操作时,另外的变量也会随之改变。
赋值

深拷贝

       python实现深拷贝依靠的copy模块,copy模块中有两种深拷贝copy.copy()和copy.deepcopy(),两者之间也有一些区别。我觉得copy.copy()属于不完全的拷贝,而copy.deepcopy()属于完全的拷贝。使用copy.deepcopy()之后生成的变量与原变量之间没有任何关系,属于那种你有的我都有,而你没有了我还是可以有的关系。copy.deepcopy()理解起来不是很难,我就着重说说对copy.copy()的理解。
深拷贝
       如图三所示,使用copy.copy()后,d会重新开辟一快新的内存,但是内存中存储的是a、b的引用,当d添加一个元素2是,c不受d的影响,但是当a添加一个元素4时,c和d都会受到影响,就是因为c和d中存储的是a和b的引用。

PS: 为什么要使用c=[a,b]呢?因为使用具体的数根本看不出效果,如果写c=[[1,2,3],[4,5,6]],修改c[1]的值修改的是引用,并不会修改原来引用的内容。

copy.copy()对可变和不可变对象的不同

  1. 可变类型使用copy
import copy
a = [1,2,3]
b = copy.copy(a)
print(id(a))
print(id(b))

a.append(4)
print(a)
print(b)

运行结果为:

1626677717832
1626677715784
[1, 2, 3, 4]
[1, 2, 3]
  1. 不可变类型使用copy
import copy
a = (1,2,3)
b = copy.copy(a)
print(id(a))
print(id(b))

运行结果为:

2043444280704
2043444280704

总结

  • 简单的赋值是浅拷贝
  • copy模块里面的copy()函数可以做一层深拷贝,虽然重新开辟了新的内存,但新内存里面仍然存放得是原来的引用,
  • copy模块中的deepcopy()函数是深拷贝,重新开辟了了内存,而且内存中保存了新的值

文中都是我个人的理解,如有错误的地方欢迎下方评论告诉我,我及时更正,大家共同进步

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xingyu97/article/details/89407983
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢