关于 python 里的值传递 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
bytest

关于 python 里的值传递

  •  
  •   bytest 2016 年 12 月 27 日 2812 次点击
    这是一个创建于 3404 天前的主题,其中的信息可能已经有所发展或是发生改变。

    python 入门很快,可是细枝末节的东西还是很多的,弄不明白。

    In [1]: list1 = list(range(5)) In [2]: for i in list1: ...: i = 100 ...: In [3]: list1 Out[3]: [0, 1, 2, 3, 4] 

    list1 没变化。

    In [4]: list2 = [] In [5]: for i in range(5): ...: list2.append(list(range(i))) ...: In [6]: list2 Out[7]: [[], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3]] In [8]: for i in list2: ...: i.append('end') ...: In [9]: list2 Out[9]: [['end'], [0, 'end'], [0, 1, 'end'], [0, 1, 2, 'end'], [0, 1, 2, 3, 'end']] 

    list2 中的每个列表都变化了,换成 dict 也是变了的。

    前面是值传递?后面是引用传递? 抱歉,我知道 c++里这么叫,请教 python 里这是什么特点?

    python 的书现在越来越多,入门的都讲的太简单,就跟给小学生看的一样,看完入门书用 python 写代码到处都是问题。 请问大家有没有推荐好些的中高级进阶的书?最好中文,看得快,不要讲 api 或者应用的,要谈语法或者语言特性的?

    被 c++虐惯了,换到 python 就只告诉你简单,可是后面的坑得自己一个一个去踩,真心不爽。

    WKPlus
        1
    WKPlus  
       2016 年 12 月 27 日
    python 里面都是引用,所以 a=x 只是把 a 指向另外一个对象并不会修改 a 原来指向的对象的值。然后, python 里面有 mutable 和 immutable 对象的概念,可以了解一下
    tonghuashuai
        2
    tonghuashuai  
       2016 年 12 月 27 日   1
    python 中不存在所谓的传值调用,一切传递的都是对象的引用,也可以认为是传址。 python 中,对象分为可变(mutable)和不可变(immutable)两种类型,元组( tuple)、数值型( number)、字符串(string)均为不可变对象,而字典型(dictionary)和列表型(list)的对象是可变对象。

    a = 1 #将名字 a 与内存中值为 1 的内存绑定在一起
    a = 2 #将名字 a 与内存中值为 2 的内存绑定在一起,而不是修改原来 a 绑定的内存中的值。
    Kilerd
        3
    Kilerd  
       2016 年 12 月 27 日
    in python ,everything is a object.
    Kilerd
        4
    Kilerd  
       2016 年 12 月 27 日
    anything
    zmj1316
        5
    zmj1316  
       2016 年 12 月 27 日
    C++ 里面的 foreach (Range-based for loop) 也是类似的吧
    crab
        6
    crab  
       2016 年 12 月 27 日
    第一次 1 个列表
    第二次是 list(range(i)) ,每一次里面又有一次列表,列表从 0 到 i 。
    bytest
        7
    bytest  
    OP
       2016 年 12 月 27 日
    @crab 我知道……
    bytest
        8
    bytest  
    OP
       2016 年 12 月 27 日
    @WKPlus
    @tonghuashuai
    谢谢二位。我知道可变和不可变对象的概念。

    自己想明白了,一直以为是 for 处理不同类型有区别,其实这里的关键在于“=”, append 方法修改了引用的对象,即列表中的列表,而“=”是重新绑定引用对象了。我试了第二个循环里如果写成 i = ['end'],原二维列表也不变了。
    bytest
        9
    bytest  
    OP
       2016 年 12 月 27 日
    @zmj1316 你是说 STL algorithm 库里的 for_each ,还是 c++11 的 range for loop ?这是两个概念。这里问题的关键在于 python 里的“=”赋值的问题。
    zmj1316
        10
    zmj1316  
       2016 年 12 月 27 日
    @bytest 我括号里说明了,并且我没看出来你这个两个样例中 python 的 = 有什么区别,因为你第二个里面没用到 = ,

    如果说你第二个里面写的是
    In [8]: for i in list2:
    ...: i = ['end']

    倒是可以有比较
    LPeJuN6lLsS9
        11
    LPeJuN6lLsS9  
       2016 年 12 月 27 日
    维基有详细解释: https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing
    这翻来覆去讨论的问题,知乎是有,不知道本站有没有

    效果和 C++的引用传递类似,不过不能用来把函数调用者作用域内的变量改掉( out parameter 可以返回元祖代替),所以不叫引用传递
    CRVV
        12
    CRVV  
       2016 年 12 月 27 日
    从行为来说, immutable 的类型和值类型一样, mutable 的类型和指针一样
    正经的解释当然是名字绑定什么的那些
    等价的 C++ 代码大概是:
    ```
    #include <iostream>
    #include <vector>

    template<typename T> void print(T& arg) {
    std::cout << arg << ", ";
    }
    template<typename T> void print(std::vector<T>* list) {
    for (auto& i : *list) {
    print(i);
    }
    std::cout << std::endl;
    }

    std::vector<int>* range(int length) {
    auto result = new std::vector<int>();
    for (int i = 0; i < length; ++i) {
    result->push_back(i);
    }
    return result;
    }
    int main() {
    auto list1 = range(5);
    print(list1);
    for (auto i : *list1) {
    i = 100;
    }
    print(list1);

    auto list2 = new std::vector<std::vector<int>*>();
    for (int i = 0; i < 5; ++i) {
    list2->push_back(range(i));
    }
    print(list2);
    for (auto i : *list2) {
    i->push_back(-1);
    }
    print(list2);
    for (auto i : *list2) {
    i = range(0);
    }
    print(list2);
    return 0;
    }
    ```
    mnzlichunyu
        13
    mnzlichunyu  
       2016 年 12 月 28 日   1
    一般这种奇怪的问题,大多数都能从 bytecode 上找到原因。楼主给的第一种情况的字节码是这样的:
    >>> dis.dis(list_change)
    2 0 LOAD_GLOBAL 0 (list)
    3 LOAD_GLOBAL 1 (range)
    6 LOAD_CONST 1 (5)
    9 CALL_FUNCTION 1
    12 CALL_FUNCTION 1
    15 STORE_FAST 0 (list1)

    3 18 SETUP_LOOP 20 (to 41)
    21 LOAD_FAST 0 (list1)
    24 GET_ITER
    >> 25 FOR_ITER 12 (to 40)
    28 STORE_FAST 1 (each)

    4 31 LOAD_CONST 2 (1)
    34 STORE_FAST 1 (each)
    37 JUMP_ABSOLUTE 25
    >> 40 POP_BLOCK
    >> 41 LOAD_CONST 0 (None)
    44 RETURN_VALUE

    您可以注意 index 为 28,34 的 STORE_FAST ,根据字节码来看,你给的第一种情况和下面的代码是等效的:
    list1 = list(range(5))
    for index in range(len(list1)):
    i = list1[index]
    i = 100

    所以, list1 的内容是不会发生改变的。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3600 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 51ms UTC 04:45 PVG 12:45 LAX 21:45 JFK 00:45
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86