zoukankan      html  css  js  c++  java
  • 【Python基础】Pass-by-object

    是时候回顾一下Python的函数传参方式了。

    Python的传参方式既不是pass-by-value(传值),也不是pass-by-reference(传引用),而是pass-by-object。

    Python中每个object都有"type", 和“identifier”:

    # int 3
    id(3) # this get the identifier
    type(3) # this get the type
    

    也有自己的name -- 但object并不知道自己被叫做什么;一个object可以被叫做很多不同的名字:

    a = 1
    b = 1 # object int 1 is called a, and also b
    

    上面的行为先将1这个整型命名为a,将a加入当前的namespace中,然后又将1再次命名为b,将b加入当前的namespace中。

    a = 1
    a = 2
    

    上面先将1命名为a,将a加入当前的namespace中,又将2命名为a,替换了之前a所指向的object。在整个过程中,只是name的指向发生了变化,namespace发生了变化,而object没有发生变化。


    Python的object分成mutable(可变)和immutable(不可变)。可变的object比如字典(dict), 列表(list);不可变的比如元组(tuple),固定字符串(string),整形,长整形,浮点数....

    def func(a):
        # do something on a
        return 
    

    当你使用a = 3; func(a)的时候,所传入的并不是a这个name,而是a所指向的object: int 3

    a = 3
    def func(a):
        a = 4
        return 
    print(a) # 3 
    

    因为int 3不是一个mutable的object,因此在func()中所做的只是在其namespace中将name a指向了object: int 4. 这个改变并不影响func()以外的namespace.

    然而,如果传入一个mutable的object,比如一个列表:

    a = []
    def func(a):
        a.append(1)
        return 
    print(a) # [1]
    

    func()中a所指向的object发生了改动,因此当函数返回时,之外的namespace中a所指向的object也发生了改动。

    另外,

    a = [1, 2, 3]
    def func(a):
        a = []
        return 
    print(a) # [1, 2, 3]
    

    这种用直接赋值方式改变mutable对象是无效的。需要使用object自带的各种method,比如列表的.appenda[0] = 1中a[0]其实也是method的语法糖而已。

    References:

    https://stackoverflow.com/questions/13299427/python-functions-call-by-reference
    http://effbot.org/zone/call-by-object.htm
    http://effbot.org/zone/python-objects.htm

  • 相关阅读:
    快速幂模板
    部分有关素数的题
    POJ 3624 Charm Bracelet (01背包)
    51Nod 1085 背包问题 (01背包)
    POJ 1789 Truck History (Kruskal 最小生成树)
    HDU 1996 汉诺塔VI
    HDU 2511 汉诺塔X
    HDU 2175 汉诺塔IX (递推)
    HDU 2077 汉诺塔IV (递推)
    HDU 2064 汉诺塔III (递推)
  • 原文地址:https://www.cnblogs.com/manqing/p/10454403.html
Copyright © 2011-2022 走看看