Python:如何通过引用传递字符串?
通过这个链接:,我们知道,当字符串作为参数传递给函数时,Python会复制字符串(一个不可变类型变量),但我认为如果字符串很大,就会浪费内存。在许多情况下,我们需要使用函数来包装字符串的某些操作,因此我想知道如何更有效地完成这些操作?Python不会复制传递给函数的对象(包括字符串):Python:如何通过引用传递字符串?,python,string,Python,String,通过这个链接:,我们知道,当字符串作为参数传递给函数时,Python会复制字符串(一个不可变类型变量),但我认为如果字符串很大,就会浪费内存。在许多情况下,我们需要使用函数来包装字符串的某些操作,因此我想知道如何更有效地完成这些操作?Python不会复制传递给函数的对象(包括字符串): >>> def foo(s): ... return id(s) ... >>> x = 'blah' >>> id(x) == foo(x) Tru
>>> def foo(s):
... return id(s)
...
>>> x = 'blah'
>>> id(x) == foo(x)
True
如果需要“修改”函数中的字符串,请返回新字符串并将其重新指定给原始名称:
>>> def bar(s):
... return s + '!'
...
>>> x = 'blah'
>>> x = bar(x)
>>> x
'blah!'
不幸的是,在对大字符串进行小更改时,这可能会非常低效,因为会复制大字符串。处理这个问题的python方法是将字符串保存在一个列表中,并在获得所有片段后将它们连接在一起。只需像传递任何其他参数一样传递它即可。内容不会被复制,只有引用会被复制
In [7]: strs="abcd"
In [8]: id(strs)
Out[8]: 164698208
In [9]: def func(x):
print id(x)
x=x.lower() #perform some operation on string object, it returns a new object
print id(x)
...:
In [10]: func(strs)
164698208 # same as strs, i.e it actually passes the same object
164679776 # new object is returned if we perform an operation
# That's why they are called immutable
但是对字符串的操作总是返回一个新的字符串对象。Python通过引用传递字符串。请注意,具有相同内容的两个字符串被视为相同:
def modify_string( t ):
the_string = t[0]
# do stuff
modify_string( ["my very long string"] )
a = 'hello'
b = 'hello'
a is b # True
因为当b由一个值赋值,并且该值已经存在于内存中时,它使用了字符串的相同引用。请注意另一个事实,如果字符串是动态创建的,即通过字符串操作(即连接)创建的,则新变量将引用同一字符串的新实例:
c = 'hello'
d = 'he'
d += 'llo'
c is d # False
也就是说,创建一个新字符串将在内存中分配一个新字符串并返回新字符串的引用,但是使用当前创建的字符串将重用同一个字符串实例。因此,将字符串作为函数参数传递将通过引用传递它,或者换句话说,将传递字符串内存中的地址
现在到了您要寻找的点-如果更改函数内部的字符串,函数外部的字符串将保持不变,这是由于字符串不可变。更改字符串意味着在内存中分配新字符串
a = 'a'
b = a # b will hold a reference to string a
a += 'a'
a is b # False
底线:
您不能真正更改字符串。与其他编程语言相同(但不要引用我的话)。
当您将字符串作为参数传递时,您将传递一个引用。当您更改它的值时,您会更改变量以指向内存中的另一个位置。但是,当您更改变量的引用时,指向同一地址的其他变量自然会保留它们持有的旧值(引用)。
希望解释足够清楚如果您想潜在地更改传入内容的值,请将其包装在dict或列表中: 这并没有改变
def x(s):
s += 1
这确实改变了s:
def x(s):
s[0] += 1
这是“按引用传递”的唯一方法。将字符串包装到类中将使其按引用传递:
class refstr:
"wrap string in object, so it is passed by reference rather than by value"
def __init__(self,s=""):
self.s=s
def __add__(self,s):
self.s+=s
return self
def __str__(self):
return self.s
def fn(s):
s+=" world"
s=refstr("hello")
fn(s) # s gets modified because objects are passed by reference
print(s) #returns 'hello world'
我不知道你在问什么。。。您是否有一些代码来演示您遇到的问题?>我们知道,当字符串(不可变类型变量)作为参数传递给函数时,Python会复制它,您肯定不知道这一点!Python从不隐式复制任何内容。Python从不通过引用传递。它传递引用,但“按引用传递”已被用作另一个参数传递样式(例如,允许函数
swap(a,b)
)。@delnan:Point-take。无论您如何称呼它,Python在将名称指定给参数时不会复制名称所引用的对象。只是术语本身有问题。其他赋值情况和其他对象也是如此,因此您可能希望概括您的答案。@delnan--也许我不是一个按CS类型的人,但您经常会看到人们用C编写函数swap(&a,&b)
,并将其称为传递引用。但是,这与您在python中实际执行的操作非常相似。可以传入对象并更改函数中的对象,但不能更改“指针”指向的位置。唯一的区别是python具有不可变对象,因此不允许更改“指针”为不可变对象引用的对象。无论如何,我从来都不清楚该如何称呼它(对于python或C)。@mgilson我同意这是通过引用传递的,因为它实现了相同的功能(我在这里只关心语义)。不同之处在于,C具有指向所有对象的指针,因此可以传递指向(例如)局部变量或结构成员的指针。在Python中,没有这样的东西——每个变量、成员、集合项等都是一个“引用”,您不能有一个“引用的引用”,因此您实际上不能做pass-by-reference(无论是内置到语言中,还是由C风格指针模拟)可以做的事情。