zoukankan      html  css  js  c++  java
  • Core Python Programming一书中关于深浅拷贝的错误

    该书关于深浅拷贝的论述:

    6.20. *Copying Python Objects and Shallow and Deep Copies

    "when shallow copies are made, the string is explicitly copied and a new (string) object created"

    这是错的.当一个容器对象被浅拷贝,字符串也是和列表一样,都只是建立引用.

    奇特的是,作者在这句话之前写有自相矛盾的句子:

    A shallow copy of an object is defined to be a newly created object of the same 
    type as the original object whose contents are references to the elements in the 
    original object.

    当然,和错误的东西相矛盾,那么自然是正确的了.

    直接上例子:

    >>> r=['a',[1]]
    >>> s=r[:]
    >>> r==s
    True
    >>> r is s
    False
    >>> id(r)
    35316200
    >>> id(s)
    35311128
    
    >>> id(r[0]),id(s[0]),   
    (19811840, 19811840)    #id相同,说明r[0]虽然是字符串对象,但是在浅拷贝过程中仍然是增加引用,并非在s[0]位置上建立了一个新的字符串对象
    >>> id(r[1]),id(s[1]),
    (35316120, 35316120)
    
    >>> r[0]='cg'
    >>> r,s
    (['cg', [1]], ['a', [1]])
    
    >>> r[1].append(2)
    >>> r,s
    (['cg', [1, 2]], ['a', [1, 2]])
    
    >>> r[1]=[]
    >>> r,s
    (['cg', []], ['a', [1, 2]])
    >>> 

     更多说明:

    >>> a='a'
    >>> b='a'
    >>> a is b
    True
    >>> a='啊啊啊士大夫'
    >>> b='啊啊啊士大夫'
    >>> a is b
    False
    >>> a='absfdsdfsdfs'
    >>> b='absfdsdfsdfs'
    >>> a is b
    True
    >>> a='啊啊啊士大夫'
    >>> b=str(a)
    >>> a is b
    True
    >>> c=a[:]
    >>> a is c
    True
    >>> import copy
    >>> d=copy.copy(a)
    >>> a is d
    True
    >>> e=copy.deepcopy(a)
    >>> a is e
    True
    >>> f=(a + ' ')[0:-1]
    >>> a is f
    False
    >>> a==f
    True
    >>> 

    SO上解释得很好:

    If you make a copy of a string itself, then the string still need not actually be copied (since it's immutable). As an optimization you could just be given back the same object again, and for most purposes that's just as good. Indeed, Python 2.7.5 and Python 3.2.5 (which are what I have installed here) both make that optimization on all three of original[:]str(original) and copy.copy(original).

    If for some obscure reason you actually want two equal strings that are not identical (perhaps to test the performance of == or something, I don't know), then you basically have to try to trick the Python runtime: (original + ' ')[0:-1] or whatever.

    我们来看看是什么意思:

    >>> a='测试字符'
    >>> b=copy.deepcopy(a)
    >>> a is b
    True
    >>> a=[1,2]
    >>> b=copy.deepcopy(a)
    >>> a is b
    False
    >>> 

    可见,深拷贝对于字符串的处理都是返回相同对象,更不用说浅拷贝那三种形式了.

  • 相关阅读:
    shell语句for循环
    ls命令详解
    计算机相关概念总结(3)
    计算机相关概念总结(2)
    计算机相关概念总结(1)
    devops的概念
    jenkins无法连接gitlab
    Jenkins创建镜像后无法推送到harbor的问题
    Jenkins+gitlab+maven持续集成
    jenkins打完包在哪里
  • 原文地址:https://www.cnblogs.com/xiangnan/p/3392587.html
Copyright © 2011-2022 走看看