首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数/方法中的参数是否通过值或引用传递?

函数/方法中的参数是否通过值或引用传递?
EN

Stack Overflow用户
提问于 2018-09-28 04:13:18
回答 1查看 144关注 0票数 2

在Python的范围内,函数/方法中的参数是通过值还是引用传递的?

我已经做了一些研究,有一个很好的资源:Are integers in Python passed by value or reference?

这个详细的一个可能是很好的参考,但它主要是关于整数。函数/方法参数的ti是怎样表示的?

我在命令行中做了一些测试/跟踪:

代码语言:javascript
复制
his_list = [1, 2, 3]
her_list = [4, 5, 6]
def change_list1(mylist):
    mylist.append(100)
    return mylist

def change_list2(mylist):
    mylist = her_list
    return mylist

test_list1 = change_list1(his_list)
test_list2 = change_list2(his_list)
print('test_list1: {}'.format(test_list1))
print('test_list2: {}'.format(test_list2))
print('his_list: {}'.format(his_list))

test_string = change_string(his_string)
print('test_string: {}'.format(test_string))
print('his_string: {}'.format(his_string))

结果是:

代码语言:javascript
复制
test_list1: [1, 2, 3, 100]
test_list2: [4, 5, 6]
his_list: [1, 2, 3, 100]
test_string: abcdef
his_string: abc

如果参数是通过引用传递的,为什么change_list2的结果似乎是通过值传递的?另外,当我将代码放在IDE中时,change_list2中的参数更改为灰色(意味着它的值未被使用)?

EN

回答 1

Stack Overflow用户

发布于 2018-09-28 04:19:45

Python按对象传递。在change_list1中,您传递一个可变对象并对其进行变异。它是同一个对象(一个列表),只是改变了(内容改变了)。mylist是引用对象的本地参数。函数返回原始对象。您会发现his_list也被修改了,因为它引用了同一个对象。

change_list2中,您还传递一个可变对象,但不是对其进行变异,而是将一个新对象分配给本地参数。原始对象不变。函数返回新对象。

将Python中的变量仅仅看作对象的名称是很有帮助的。将参数传递给函数时,函数中参数的名称只是传递给函数的原始对象的新名称。

您可以通过打印传递给函数的对象名的ID和参数的对象名称的ID来看到这一点:

代码语言:javascript
复制
a = [1,2,3] # mutable object (content can be altered)
b = 1       # immutable object (content can't be altered).

print(f'id(a) = {id(a)}, id(b) = {id(b)}')

def func(c,d):
    print('INSIDE func')
    print(f'id(c) = {id(c)}, id(d) = {id(d)}')
    c.append(4)  # mutable object can be altered.
    d = 4        # local name 'd' assigned a new object.
    print('AFTER altering c & d')
    print(f'id(c) = {id(c)}, id(d) = {id(d)}')
    return c,d

e,f = func(a,b)

print('AFTER func called')
print(f'id(a) = {id(a)}, id(b) = {id(b)}')
print(f'id(e) = {id(e)}, id(f) = {id(f)}')

print(f'a = {a}, b = {b}')
print(f'e = {e}, f = {f}')

输出:

代码语言:javascript
复制
id(a) = 2290226434440, id(b) = 1400925216
INSIDE func
id(c) = 2290226434440, id(d) = 1400925216
AFTER altering c & d
id(c) = 2290226434440, id(d) = 1400925312
AFTER func called
id(a) = 2290226434440, id(b) = 1400925216
id(e) = 2290226434440, id(f) = 1400925312
a = [1, 2, 3, 4], b = 1
e = [1, 2, 3, 4], f = 4

注意,ab的ID与参数名称cd重合。名称指的是相同的对象。

c对象会发生变异。a引用相同的对象,因此将显示相同的更改。

d对象是不可变的。没有像.append这样的方法来改变对象的内容。d只能重新分配。它将被重新分配,并显示一个新的ID. b对象不变。

函数调用之后,e成为名为c (也称为a)的对象的新名称。名称c不再存在。这是一个本地函数名。f成为对象d (整数4)的新名称,d不再存在。b不受影响,并引用原始整数1。

ae引用原始的、但经过变异的对象。bf指不同的、不变的对象。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52548178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档