在 Python 中传递值

发布于 2024-07-13 15:17:08 字数 54 浏览 14 评论 0原文

当你将像列表、数组这样的集合传递给Python中的另一个函数时,它会复制它,还是只是一个指针?

When you pass a collection like list, array to another function in python, does it make a copy of it, or is it just a pointer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

千年*琉璃梦 2024-07-20 15:17:08

Python 按值传递对象引用。

Python 通过以下方式传递对对象的引用
值(如 Java),以及其中的所有内容
Python 是一个对象。 这听起来
很简单,但是你会注意到
某些数据类型似乎表现出
按值传递特征,同时
其他人似乎表现得像
传递引用...这是怎么回事?

了解可变性很重要
和不可变的对象。 一些物体,
就像字符串、元组和数字一样,
不可变的。 在 a 内改变它们
函数/方法将创建一个新的
实例和原始实例
函数/方法之外不是
改变了。 其他对象,例如列表
并且字典是可变的,这
意味着你可以改变对象
到位。 因此,改变一个
函数/方法内的对象将
也改变原来的对象
外面。

Python passes references-to-objects by value.

Python passes references-to-objects by
value (like Java), and everything in
Python is an object. This sounds
simple, but then you will notice that
some data types seem to exhibit
pass-by-value characteristics, while
others seem to act like
pass-by-reference... what's the deal?

It is important to understand mutable
and immutable objects. Some objects,
like strings, tuples, and numbers, are
immutable. Altering them inside a
function/method will create a new
instance and the original instance
outside the function/method is not
changed. Other objects, like lists
and dictionaries are mutable, which
means you can change the object
in-place. Therefore, altering an
object inside a function/method will
also change the original object
outside.

骷髅 2024-07-20 15:17:08

问题是,整个引用/值概念不适合 python。 Python 没有变量的“值”。 Python 只有对象和引用对象的名称。

因此,当您调用函数并在括号内放入“名称”时,如下所示:

def func(x): # defines a function that takes an argument
    ... # do something here

func(myname) # calling the function

传递 myname 指向的实际对象,而不是 name myname 本身。 在函数内部,给出了另一个名称 (x) 来引用传递的同一对象。

如果函数内部的对象是可变的,您可以修改该对象,但您无法更改外部名称所指向的内容。 与您这样做时发生的情况相同

anothername = myname

因此我可以回答您的问题:

它是“按值传递”,但所有值都只是对对象的引用。

Thing is, the whole reference/value concept won't fit into python. Python has no "value" of a variable. Python has only objects and names that refer to objects.

So when you call a function and put a "name" inside the parenthesis, like this:

def func(x): # defines a function that takes an argument
    ... # do something here

func(myname) # calling the function

The actual object that myname is pointing is passed, not the name myname itself. Inside the function another name (x) is given to refer to the same object passed.

You can modify the object inside the function if it is mutable, but you can't change what the outside name is pointing to. Just the same that happens when you do

anothername = myname

Therefore I can answer your question with:

it is "pass by value" but all values are just references to objects.

清风疏影 2024-07-20 15:17:08

这里的答案很有帮助,但我发现有必要展示这种我没有看到的细微区别,我已经通过后续的 CL 实验向自己证明了这一点:

  1. 单独的不可变对象不能在函数内更改(到目前为止的答案已经说了这么多...)
  2. 但是,包含在可变对象中的不可变对象可以在方法调用中重新分配。

“num”不会在这里进行更改,因为它是一个不可变的 Number 对象 [支持我的观点 1.]:

>>> def incr_num(num):
        num += 1

>>> num = 0

>>> num
0

>>> incr_num(num)

>>> num
0

list[0] 这里也是一个不可变的 Number 对象。

>>> def incr_list(list):
        list[0] += 1

>>> list = [0]

>>> list[0]
0

>>> incr_list(list)

>>> list[0]
1

那么,作为一个不可变的 Number 对象,list[0] 是如何改变的(支持我的观点 2),而上面示例的 Number 对象“num”却没有改变? Number 对象 list[0] 包含在可变列表对象“list”中,而第一个示例中的“num”只是一个非包含的 Number 对象( >不可变)。

虽然出发点是好的,但我觉得 @Stephen Pape 评价最高的答案(在下面引用),以及其他一些类似的答案,并不完全正确(这促使我写下这个答案):

一些对象,如字符串、元组和数字,是不可变的。
在函数/方法内更改它们将创建一个新实例并
函数/方法之外的原始实例不会更改。

我上面的第二个代码实验显示了一个 Number 对象('list[0]')在方法内被更改,然后函数外部的原始实例发生了更改。

Answers here have been helpful, but I find the need to exhibit this fine distinction which I haven't seen covered, which I've proven to myself with the subsequent CL experiment:

  1. An immutable object ALONE CANNOT be changed within a function call. (answers so far have said that much...)
  2. BUT, an immutable object CONTAINED WITHIN a mutable object CAN be re-assigned within a method call.

'num' does not change here because it is an immutable Number object [supports my point 1.]:

>>> def incr_num(num):
        num += 1

>>> num = 0

>>> num
0

>>> incr_num(num)

>>> num
0

list[0] here is an immutable Number object also.

>>> def incr_list(list):
        list[0] += 1

>>> list = [0]

>>> list[0]
0

>>> incr_list(list)

>>> list[0]
1

So how did list[0], being an immutable Number object, change (supports my point 2.) while the above example's Number object 'num' did not? The immutable Number object list[0] is contained within the mutable list object 'list', while 'num' from the 1st example is just a non-contained Number object (immutable).

Although well-intended, I feel @Stephen Pape top-rated answer (quoted below), and some other similar ones, were not totally correct (and that motivated me to write this answer):

Some objects, like strings, tuples, and numbers, are immutable.
Altering them inside a function/method will create a new instance and
the original instance outside the function/method is not changed.

My 2nd code experiment above shows a Number object ('list[0]') being altered within a method, and then the original instance outside the function changed.

行雁书 2024-07-20 15:17:08

传递引用,但如果参数是不可变对象,则在方法内修改它将创建一个新实例。

A reference is passed, but if the parameter is an immutable object, modifying it within the method will create a new instance.

猫性小仙女 2024-07-20 15:17:08

对象已传递。 不是副本,而是对底层对象的引用。

The object is passed. Not a copy, but a reference to the underlying object.

但可醉心 2024-07-20 15:17:08

引用:

>>> x = [0,1,2,3]
>>> def foo(x_list):
    x_list[0] = 1


>>> foo(x)
>>> x
[1, 1, 2, 3]

By reference:

>>> x = [0,1,2,3]
>>> def foo(x_list):
    x_list[0] = 1


>>> foo(x)
>>> x
[1, 1, 2, 3]
十年不长 2024-07-20 15:17:08

我还建议查看 copy 模块:

Python 复制文档< /a>

它将帮助您了解根本问题以及如何使用它来执行您自己的深层复制。

I would also recommend looking at the copy module:

Python documentation for copy

It will help you to understand the underlying issues and how to use it to perform your own deep copy.

素年丶 2024-07-20 15:17:08

请让我举一个简单的例子

def swap(a, b):
    x = a
    print id(x)
    print id(a)
    print id(b)
    a = b
    
    print id(a)
    b = x
    print id(b)
    a[0]= '20'
    



var1 = ['1','2','3','4']
var2 = ['5','6','7','8','9']
print id(var1)
print id(var2)

swap(var1, var2)

print id(var1)
print id(var2)
print var1
print var2

,它会产生以下结果

28329344 var1
28331264 var2
28329344 x
28329344 a
28331264 b
After a = b
28331264 a
after b = x
28329344 b
after return
28329344 var1
28331264 var2
['1', '2', '3', '4']
['20', '6', '7', '8', '9']

Mapping to the memory addresses
28329344                 28331264 
var1                     var2
a                        b
x
After a=b
                         a
After b=x
b
After a[0] = '20'
                         [0] = '20'
After return
['1','2','3','4']        ['20', '6', '7', '8', '9']

Please let me give a humble example

def swap(a, b):
    x = a
    print id(x)
    print id(a)
    print id(b)
    a = b
    
    print id(a)
    b = x
    print id(b)
    a[0]= '20'
    



var1 = ['1','2','3','4']
var2 = ['5','6','7','8','9']
print id(var1)
print id(var2)

swap(var1, var2)

print id(var1)
print id(var2)
print var1
print var2

which produces the following result

28329344 var1
28331264 var2
28329344 x
28329344 a
28331264 b
After a = b
28331264 a
after b = x
28329344 b
after return
28329344 var1
28331264 var2
['1', '2', '3', '4']
['20', '6', '7', '8', '9']

Mapping to the memory addresses
28329344                 28331264 
var1                     var2
a                        b
x
After a=b
                         a
After b=x
b
After a[0] = '20'
                         [0] = '20'
After return
['1','2','3','4']        ['20', '6', '7', '8', '9']
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文