美文网首页
Python函数传递参数:对象引用

Python函数传递参数:对象引用

作者: 惑也 | 来源:发表于2018-12-27 21:53 被阅读23次

    一、变量与对象

    1. Python 中一切皆为对象,数字是对象,列表是对象,函数也是对象,任何东西都是对象。

    2. 变量是对象的一个引用,又称名字或者标签,对象的操作都是通过引用来完成的。

    3. 赋值操作 = 就是把一个引用绑定到一个对象上。例如,[]是一个空列表对象,赋值给变量a,变量 a 是该对象的一个引用。

    a = []
    a.append(1)
    

    二、对象的可变性

    1. 不可变对象:对象所指向的内存中的值不能被改变。不可变对象赋值给变量后,由于变量指向的值不可变,如果改变变量(准确的说是引用),相当于对变量进行了重新赋值,指向了内存中新的值。
    • 变量a引用了内存中的对象:1
    a = 1
    
    • 对象1在内存中的地址
    print(a, id(1))     
    print(a, id(a))
    1 4496995664
    1 4496995664
    
    • 变量a重新赋值,引用了内存中的对象:2
    a = 2
    
    • 对象2在内存中的地址
    print(a, id(2))
    print(a, id(a))
    2 4496995696
    2 4496995696
    


    2. 可变对象:对象所指向的内存中的值可以被改变。如果改变变量(准确的说是引用),实际上只是对其所指的值进行了变更,并没有产生新的值,通俗点说就是原地改变。

    lt = [1, 2, 3]
    print(id(lt))
    4551719624
    
    lt.append(100)
    print(id(lt))
    4551719624
    
    1. Python中,数值类型(int和float)、字符串str、元组(tuple)都是不可变类型,而列表(list)、字典(dict)、集合(set)是可变类型。

    三、函数传参

    1. Python函数中,参数传递的全部都是对象的引用,本质上是赋值操作,即把一个引用(变量)绑定到一个对象上。

    2. 参数是不可变对象时,不会对对象进行修改,相当于传递值。

    3. 参数是可变对象时,会对对象进行修改,相当传递引用。

    4. 在定义函数时,要注意函数的参数,传递的是值还是引用,特别是对于 默认参数 ,很容易导致潜在的bug。

    四、函数的默认参数

    1. 默认参数是传递值时,仅仅在函数定义的时候赋值一次。
    x = 8
    
    def func(a, b=x):
        return a, b
    
    print(func(1))
    (1, 8)
    
    x = 20
    print(func(1))
    (1, 8)
    
    • 示例中,默认参数b赋值为xx为不可变对象字符串8,当对x重新赋值为20后,调用函数时,默认参数b的值仍然为8
    • 默认参数的值,通常应该是不可变的对象,比如None、True、False、数字或字符串。
    1. 默认参数是传递引用时,通常为空,比如空列表[]或空集合{},但在定义函数时,尽量设置为None,而不要让参数直接等于空列表或空集合。
    def fun(a, b = []):
        return b 
    
    f = fun(1)
    print(f)
    []
    
    f.append(100)
    print(f)
    [100]
    
    • 像上述示例中,如果设置默认参数b = [],因为是可变对象,当默认参数b的对象,在其他地方被修改后,下次调用这个函数时其默认参数b 已不再是空列表。
    • 特殊情况下,比如在for循环中,调用默认参数为空列表[]或空集合{}的函数,可以循环累积迭代结果。

    五、匿名函数捕获参数值

    1. lambda表达式中的参数x是一个自由变量, 是在执行时赋值(绑定),而不是定义时赋值(绑定),即lambda表达式中的参数x是执行时的值,这与函数的 默认参数 赋值不相同。
    x = 10
    a = lambda y: y + x
    
    x = 20 
    print(a(10))
    30
    

     示例中,调用a(10)时,x取值为20,而不是定义时的10

    1. 如果想让匿名函数,在定义时就捕获到参数值,将参数x定义成默认参数即可,例如:
    z = 10
    a = lambda x, z=z: x + z 
    
    print(a(2))
    12
    
    z = 7
    print(a(2))
    12
    

     示例中,对变量z重新赋值为7,再次调用函数a(2)时,匿名函数的参数z的值仍
     然为定义时的10,而不是7

    相关文章

      网友评论

          本文标题:Python函数传递参数:对象引用

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