简体   繁体   English

Python:如何通过引用传递字符串?

[英]Python: How do I pass a string by reference?

From this link: How do I pass a variable by reference?从这个链接: 如何通过引用传递变量? , we know, Python will copy a string (an immutable type variable) when it is passed to a function as a parameter, but I think it will waste memory if the string is huge. ,我们知道,Python 在将字符串(一个不可变类型变量)作为参数传递给函数时会复制它,但我认为如果字符串很大会浪费内存。 In many cases, we need to use functions to wrap some operations for strings, so I want to know how to do it more effective?很多情况下,我们需要用函数来包装一些对字符串的操作,所以我想知道如何做更有效?

Python does not make copies of objects (this includes strings) passed to functions: Python 不会复制传递给函数的对象(包括字符串):

>>> def foo(s):
...     return id(s)
...
>>> x = 'blah'
>>> id(x) == foo(x)
True

If you need to "modify" a string in a function, return the new string and assign it back to the original name:如果你需要在函数中“修改”一个字符串,返回新的字符串并将其赋值回原来的名称:

>>> def bar(s):
...     return s + '!'
...
>>> x = 'blah'
>>> x = bar(x)
>>> x
'blah!'

Unfortunately, this can be very inefficient when making small changes to large strings because the large string gets copied.不幸的是,当对大字符串进行小的更改时,这可能非常低效,因为大字符串会被复制。 The pythonic way of dealing with this is to hold strings in an list and join them together once you have all the pieces.处理这个问题的 pythonic 方法是将字符串保存在一个列表中,并在你拥有所有部分后将它们连接在一起。

Python does pass a string by reference. Python确实通过引用传递字符串。 Notice that two strings with the same content are considered identical:请注意,具有相同内容的两个字符串被认为是相同的:

a = 'hello'
b = 'hello'
a is b        # True

Since when b is assigned by a value, and the value already exists in memory, it uses the same reference of the string.因为当 b 被赋值,并且该值已经存在于内存中时,它使用字符串的相同引用。 Notice another fact, that if the string was dynamically created, meaning being created with string operations (ie concatenation), the new variable will reference a new instance of the same string:请注意另一个事实,如果字符串是动态创建的,意味着是通过字符串操作(即连接)创建的,新变量将引用同一字符串的新实例:

c = 'hello'
d = 'he'
d += 'llo'
c is d        # False

That being said, creating a new string will allocate a new string in memory and returning a reference for the new string, but using a currently created string will reuse the same string instance.也就是说,创建一个新字符串将在内存中分配一个新字符串并返回新字符串的引用,但使用当前创建的字符串将重用相同的字符串实例。 Therefore, passing a string as a function parameter will pass it by reference, or in other words, will pass the address in memory of the string.因此,将字符串作为函数参数传递通过引用传递它,或者换句话说,将传递字符串在内存中的地址。

And now to the point you were looking for- if you change the string inside the function, the string outside of the function will remain the same, and that stems from string immutability.现在到了您正在寻找的地方 - 如果您更改函数内部的字符串,函数外部的字符串将保持不变,这源于字符串不变性。 Changing a string means allocating a new string in memory.更改字符串意味着在内存中分配一个新字符串。

a = 'a'
b = a    # b will hold a reference to string a
a += 'a'
a is b   # False

Bottom line:底线:

You cannot really change a string.你不能真正改变一个字符串。 The same as for maybe every other programming language (but don't quote me).可能与其他所有编程语言一样(但不要引用我的话)。 When you pass the string as an argument, you pass a reference.当您将字符串作为参数传递时,您传递了一个引用。 When you change it's value, you change the variable to point to another place in memory.当您更改它的值时,您会将变量更改为指向内存中的另一个位置。 But when you change a variable's reference, other variables that points to the same address will naturally keep the old value (reference) they held.但是,当您更改变量的引用时,指向同一地址的其他变量自然会保留它们所持有的旧值(引用)。 Wish the explanation was clear enough希望解释足够清楚

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  

But operations on strings always return a new string object.但是对字符串的操作总是返回一个新的字符串对象。

def modify_string( t ):
  the_string = t[0]
  # do stuff

modify_string( ["my very long string"] )

If you want to potentially change the value of something passed in, wrap it in a dict or a list:如果您想潜在地更改传入的某些内容的值,请将其包装在字典或列表中:

This doesn't change s这不会改变 s

def x(s):
  s += 1

This does change s:这确实改变了:

def x(s):
  s[0] += 1

This is the only way to "pass by reference".这是“通过引用传递”的唯一方法。

wrapping the string into a class will make it pass by reference:将字符串包装到一个类中将使其通过引用传递:

    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' 

Just pass it in as you would any other parameter.就像传递任何其他参数一样传递它。 The contents won't get copied, only the reference will.内容不会被复制,只有引用会。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM