开发者

Reference or Copy

I just started with Python 3. In a Python book i read that the interpreter can be forced to make a copy of a instance instead creating a 开发者_开发知识库reference by useing the slicing-notation.

This should create a reference to the existing instance of s1:

s1 = "Test"
s2 = s1
print(s1 == s2)
print(s1 is s2)

This should create a new instance:

s1 = "Test"
s2 = s1[:]
print(s1 == s2)
print(s1 is s2)

When running the samples above both return the same result, a reference to s1. Can sombody explain why it's not working like described in the book? Is it a error of mine, or a error in the book?


This is true for mutable datatypes such as lists (i.e. works as you expect with s1 = [1,2,3]).

However strings and also e.g. tuples in python are immutable (meaning they cant be changed, you can only create new instances). There is no reason for a python interpreter to create copies of such objects, as you can not influence s2 via s1 or vice versa, you can only let s1 or s2 point to a different string.


Since strings are immutable, there's no great distinction between a copy of a string and a new reference to a string. The ability to create a copy of a list is important, because lists are mutable, and you might want to change one list without changing the other. But it's impossible to change a string, so there's nothing to be gained by making a copy.


Strings are immutable in Python. It means, that once a string is created and is written to the memory, it could not be modified at all. Every time you "modify" a string, a new copy is created.
You may notice another interesting behaviour of CPython:

s1 = 'Test'
s2 = 'Test'
id(s1) == id(s2)
>>> True

As you can see, in CPython s1 and s2 refer to the same address in the memory.

If you need a full copy of a mutable object (e.g. a list), check the copy module from the standard library. E.g.

import copy

l1 = [1,2,3]
l2 = l1
id(l2) == id(l1) # a reference
>>> True

l3 = copy.deepcopy(l1)
id(l3) == id(l1)
>>> False     


The slice-as-copy give you a new copy of the object only if it's applied to a list:

>>> t = ()
>>> t is t[:]
True
>>> l = []
>>> l is l[:]
False
>>> s = ''
>>> s is s[:]
True

There was already some discussion in the python-dev mailing list of a way to make slice-as-copy work with strings but the feature was rejected due to performance issues.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜