Python中的子字符串。内存中的副本?

Python中的子字符串。内存中的副本?,python,regex,string,immutability,Python,Regex,String,Immutability,假设我在Python中有一个字符串my_string,并根据some_模式对其进行标记: match.re.search(some_pattern, my_string) string_1 = match.group(1) string_2 = match.group(2) .... string_1和string_2(“深”)是my_string中的子字符串的副本还是对内存中相同位置的引用?string_1和string_2是否为my_string中的字符的完整副本分配内存 请注意,我不是在

假设我在Python中有一个字符串
my_string
,并根据
some_模式对其进行标记:

match.re.search(some_pattern, my_string)
string_1 = match.group(1)
string_2 = match.group(2)
....
string_1
string_2
(“深”)是
my_string
中的子字符串的副本还是对内存中相同位置的引用?
string_1
string_2
是否为
my_string
中的字符的完整副本分配内存

请注意,我不是在询问字符串的不变性。如果
my_string
很长,我想知道通过标记字符串在内存中的命中率是多少


我不需要确切地知道有多少内存被重复使用,但如果知道字符串的标记化是否会导致内存的重复,肯定会很有用。

字符串在python中是不可变的,因此子字符串只不过是新对象

In [7]: str="foobar"

In [8]: id(str)
Out[8]: 140976032

In [10]: id(str[:4])
Out[10]: 141060224
返回的子字符串对象与原始字符串对象相同的唯一情况是
string==substring

In [16]: foo="foobar"

In [17]: id(foo)
Out[17]: 140976032

In [18]: id(foo[:])
Out[18]: 140976032

In [19]: foo="foobar"*10000   # huge string

In [20]: id(foo)
Out[20]: 141606344

In [21]: id(foo[:])
Out[21]: 141606344

Python字符串是不可变的,因此这种区别在本例中没有什么意义,但它们是副本。查看Python 2.7.3源代码时,对
string_1
string_2
所做的任何操作都不会影响
my_string

的内容,取一段字符串就可以复制字符数据:

Objects/stringobject.c

string\u slice()
调用以下函数,
PyString\u FromStringAndSize()

这里,
str
是指向字符数据的指针,
size
是长度。注意malloc和memcpy


不同的Python实现(以及不同版本的CPython)的行为可能不同。例如,Jython可能使用,它不会复制。

不确定它有多大帮助,甚至不能回答您的问题,但您可以使用
finditer
,然后仅在需要时对原始字符串进行切片

>>> import re
>>> string = 'abcdefhijkl'
>>> matches = list(re.finditer('.' , string))
>>> dir(matches[0])
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'end', 'endpos', 'expand', 'group', 'groupdict', 'groups', 'lastgroup', 'lastindex', 'pos', 're', 'regs', 'span', 'start', 'string']
>>> matches[0].span()
(0, 1)

然后从那里开始…

一个跟不上另一个。在Java中,字符串是不可变的,但是子字符串引用原始字符串的存储。我知道它们是不变的。请参阅我在OP.@user273158中的注释。在python中,子字符串总是会导致一个新对象,但是在一些小字符串的情况下,您可能会看到python在内部执行一些缓存,但是返回的子字符串应该等于字符串。谢谢,但我不是问字符串的不变性。我知道他们是一成不变的。为什么要投否决票?请注意,我不是在问字符串的不变性,我知道字符串在Python中是不可变的。请记住,您询问的是一个非常具体的实现细节,它在Python版本之间可能会发生变化,并且在Python实现之间至少会有细微的差异。另一个提示是:现在有一种方法可以构建字符串数据的视图。
>>> import re
>>> string = 'abcdefhijkl'
>>> matches = list(re.finditer('.' , string))
>>> dir(matches[0])
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'end', 'endpos', 'expand', 'group', 'groupdict', 'groups', 'lastgroup', 'lastindex', 'pos', 're', 'regs', 'span', 'start', 'string']
>>> matches[0].span()
(0, 1)