python的赋值传递

python的参数传递是赋值传递,或者称为对象的引用传递;既不是值传递,也不是引用传递。「“Call by Object Reference” or “Call by assignment”.」

引用python官方文档中的一句话:
“Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there’s no alias between an argument name in the caller and callee, and so no call-by-reference per Se.”

python中的数据类型大致分为2类:

  • 不可变: 数值、字符串、元组
  • 可变: 列表、字典、集合

给出一个demo:

def f_list(i: list):
    print("list id init:", id(i))
    print("list:", i)
    i += [2]
    print("list id:", id(i))


def f_dict(n: dict):
    print("dict id init:", id(n))
    print("dict:", n)
    n |= {"c": "d"}
    print("dict id:", id(n))


def f_int(m: int):
    print("int id init:", id(m))
    print("int:", m)
    m += 1
    print("int id:", id(m))


def f_str(o: str):
    print("str id init:", id(p))
    print("str:", o)
    o += "o"
    print("str id:", id(o))


if __name__ == '__main__':
    i = [0]
    print("list id init:", id(i))
    f_list(i)
    print(f"list: {i}\n")

    n = {"a": "b"}
    print("dict id init:", id(n))
    f_dict(n)
    print(f"dict: {n}\n")

    m = 1
    print("int id init:", id(m))
    f_int(m)
    print(f"int: {m}\n")

    p = "k"
    print("str id init:", id(p))
    f_str(p)
    print(f"str: {p}\n")

我们看一下输出:

list id init: 4545683712
list id init: 4545683712
list: [0]
list id: 4545683712
list: [0, 2]

dict id init: 4544160960
dict id init: 4544160960
dict: {'a': 'b'}
dict id: 4544160960
dict: {'a': 'b', 'c': 'd'}

int id init: 4543166768
int id init: 4543166768
int: 1
int id: 4543166800
int: 1

str id init: 4544020656
str id init: 4544020656
str: k
str id: 4545737008
str: k

我们通过观察id可以看到:

  • 以list和dict为代表的可变数据结构的数据类型在函数处理后,原变量的值发生了变化;
  • 以str和int为代表的不可变数据结构的数据类型在函数处理后,原变量的值保持不变。

这也可以证明了python既不是值传递,否则同一个值的内存id不应该是一样的;也不是引用传递,因为字符串和数值在函数处理后,id发生了变化,但值本身并没有发生改变。

所以总之,Python 中参数的传递既不是值传递,也不是引用传递,而是赋值传递,或者是叫对象的引用传递。

一些参考链接:

  1. is-python-call-by-reference-or-call-by-value
  2. python-pass-by-reference

Tips: 如有不当之处,请指正。

本作品采用《CC 协议》,转载必须注明作者和本文链接
Stay hungry, stay foolish.
讨论数量: 2

说实话,这个代码挺让人为难的

2年前 评论
runstone (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!