美文网首页
Python初学者笔记(八):函数参数的值传递和引用传递

Python初学者笔记(八):函数参数的值传递和引用传递

作者: eftales | 来源:发表于2020-08-12 11:02 被阅读0次

    函数参数的值传递和引用传递

    像我们最熟悉的 C 语言,再写函数参数的同时需要规定函数参数到底是值传递还是引用传递。引用传递导致该参数在函数内的修改出了函数之外也会生效,值传递所有的修改都不会体现到函数外部。

    Python 稍微有一点特殊,在定义函数的时候不允许选择参数的传递的方式,传递方式只与参数的数据类型有关。

    Python 有 6 中标准的数据类型:Number,String,List,Tuple,Set,Dictionary。不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。再加上自定义对象,共 7 种数据类型。

    其中不可变数据(Number,String,Tuple)为值传递,可变数据(List,Dictionary,Set)和自定义对象为引用传递。

    举几个例子就明白了。

    Number 值传递

    Number 又包含 int、float、bool、complex。

    for i in [0,1.2,True,4+3j]:
        print("**--------**")
        print(i)
        def testint(i):
            i = 0
        testint(i)
        print(i)
    
        j = i
        j = 0
        print(i,j)
    

    输出:

    **--------**
    0
    0
    0 0
    **--------**
    1.2
    1.2
    1.2 0
    **--------**
    True
    True
    True 0
    **--------**
    (4+3j)
    (4+3j)
    (4+3j) 0
    
    1. 函数内的参数值的改变不会影响到外部

    2. 把 i 用 = 赋值给 j,i 和 j 互不影响

    String 值传递

    和 Number 一样:

    1. 函数内的参数值的改变不会影响到外部

    2. 把 i 用 = 赋值给 j,i 和 j 互不影响

    for i in ["11","abc"]:
        print("**--------**")
        print(i)
        def testint(i):
            i = "www"
        testint(i)
        print(i)
    
        j = i
        j = "555"
        print(i,j)
    
    **--------**
    11
    11
    11 555
    **--------**
    abc
    abc
    abc 555
    

    Tuple 值传递

    用的很少,不举例子喽。

    List 引用传递

    1. 函数内的参数值的改变会影响到外部

    2. 把 i 用 = 赋值给 j,对 j 进行除新赋值之外的任何操作都会影响到 i

    3. 把 j 赋值成另外的值并不会导致 i 也变成同样的值

    l = [1,2,3,4,5,6]
    print("**--------**")
    print(l)
    def testint(l):
        l.pop()
    testint(l)
    print(l)
    
    j = l
    j.pop()
    print(l,j)
    j = ["555","666"]
    print(l,j)
    

    Dictionary 引用传递

    1. 函数内的参数值的改变会影响到外部

    2. 把 i 用 = 赋值给 j,对 j 进行除新赋值之外的任何操作都会影响到 i

    3. 把 j 赋值成另外的值并不会导致 i 也变成同样的值

    l = dict()
    l[1] = 1
    l[2] = 2
    print("**--------**")
    print(l)
    def testint(l):
        l.pop(1)
    testint(l)
    print(l)
    
    j = l
    j.pop(2)
    print(l,j)
    j = ["555","666"]
    print(l,j)
    

    Set 引用传递

    1. 函数内的参数值的改变会影响到外部

    2. 把 i 用 = 赋值给 j,对 j 进行除新赋值之外的任何操作都会影响到 i

    3. 把 j 赋值成另外的值并不会导致 i 也变成同样的值

    l = set()
    l.add(1)
    l.add(2)
    print("**--------**")
    print(l)
    def testint(l):
        l.remove(1)
    testint(l)
    print(l)
    
    j = l
    j.remove(2)
    print(l,j)
    j = ["555","666"]
    print(l,j)
    

    自定义对象 引用传递

    将自定义对象或将自定义对象封装在 List/Tuple 种作为参数:

    1. 函数内的参数值的改变会影响到外部

    2. 把 i 用 = 赋值给 j,对 j 进行除新赋值之外的任何操作都会影响到 i

    3. 把 j 赋值成另外的值并不会导致 i 也变成同样的值

    class Node:
        def __init__(self, val = 0, neighbors = []):
            self.val = val
            self.neighbors = neighbors
    
    n1 = Node(1)
    n2 = Node(2)
    nl = [n1,n2]
    print(nl[0].val)
    def t22(nodeList):
        nodeList[0].val = 0
    t22(nl)
    print(nl[0].val)
    
    def t222(node):
        node.val = 0
    
    print(n2.val)
    t222(n2)
    print(n2.val)
    
    • tips

      当自定义类的属性有引用传递对象时,需要将该引用传递对象 copy 一下再传入自定义对象。

    class Node:
        def __init__(self, val = 0, neighbors = []):
            self.val = val
            self.neighbors = neighbors
    
    l = [1,2,3,4]
    n1 = Node(1,l)
    n2 = Node(2,l)
    nl = (n1,n2)
    print(nl[0].neighbors,nl[1].neighbors,l)
    def t22(nodeList):
        nodeList[0].neighbors.pop()
    t22(nl)
    print(nl[0].neighbors,nl[1].neighbors,l)
    print(l)
    
    print("---------")
    n1 = Node(1,l.copy())
    n2 = Node(2,l.copy())
    nl = (n1,n2)
    print(nl[0].neighbors,nl[1].neighbors,l)
    def t22(nodeList):
        nodeList[0].neighbors.pop()
    t22(nl)
    print(nl[0].neighbors,nl[1].neighbors,l)
    print(l)
    

    输出:

    [1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4]
    [1, 2, 3] [1, 2, 3] [1, 2, 3]
    [1, 2, 3]
    ---------
    [1, 2, 3] [1, 2, 3] [1, 2, 3]
    [1, 2] [1, 2, 3] [1, 2, 3]
    [1, 2, 3]
    

    相关文章

      网友评论

          本文标题:Python初学者笔记(八):函数参数的值传递和引用传递

          本文链接:https://www.haomeiwen.com/subject/ugepdktx.html