能否用C++的指针/引用来类比解释一下Python中Tuple的“指向不变性”?
怪我咯
怪我咯 2017-04-17 16:32:10
0
6
412

初学Python,有一定C/C++基础。
看到Tuple的"immutable"的时候产生了这样一个疑问。
根据我的理解,如果Tuple的元素是普通变量(e.g. myInt=5),那创建
myTuple=(myInt,)
的意义就是
myTuple=(myInt的值,)
因此是不变的。

但是如果myTuple=(myInt,myList),虽然myTuple[1]永远都指向myList,但是myList中的内容是可以改变的。看到有人表示这Tuple里的List实际上是myList的引用。那能否用C++的指针/引用来类比统一解释一下这种Tuple元素的immutable特性呢?

【补充一下:比如对于myTuple=(myInt,myList),定义的时候,从意义上感觉(非严谨),就像是用C++写:
myTuple[0]=myInt; //myInt之后发生了什么都和myTuple[0]无关了,myTuple[0]只决定于myInt当前值
&myTuple[1]=myList; //而myTuple[1]更像是myList的一个引用。myList如果变化,myTuple[1]也会变化

于是这里就产生了“同样是对Tuple赋值,却有两种不同的意义”的矛盾。有什么解释方式能调和这种矛盾么?】

表述的不太清楚,希望能有理解了我的疑问的朋友呀。多谢了。

怪我咯
怪我咯

走同样的路,发现不同的人生

Antworte allen (6)
洪涛

你的类比是错误的。myTuple=(myInt,myList)在任何时候都是:

&myTuple[0]=myInt; &myTuple[1]=myList;

因为在Python里一切都是对象,myInt也是。tupleimmutable的意思是你无法为其元素重新赋值。也就是你不能改变myTuple[0]myTuple[1]这两个指针变量的值,所以它们永远指向myIntmyList,这一点是确定的。

但是你可以修改tuple中的每个元素所指向的对象本身,前提是这个对象必须是可变的。比如你能够修改myList,因为这是一个可变对象。但是myInt不行,因为整数也是不可变对象,所以你无法修改它。

    刘奇

    你把指针理解成一张上面写有数字的小纸条,纸条上面的数字告诉你该去对应哪一个编号的抽屉里面拿东西。

    那么 Tuple 是这样的:

    1. 当你有一个 myTuple 的时候,你有一张名字叫 myTuple 的纸条,根据数字你可以找到一个抽屉,抽屉里面有一张或者多张另外的小纸条。并且这些纸条的数量是确定的,直到你把 myTuple 这张纸条扔掉了(或者说 myTuple 上的数字换了另外一个),才有可能会变化。

    2. myTuple 从(myInt,)变成(myInt, myList)的过程,实际上是 myTuple 上面的数字改写了,并且向新的数字对应的另外一个抽屉,放进去两张纸条:第一张是原先的 myInt 纸条,第二张是新加进去的 myList 纸条。

    3. 你对 myList 添加或者删除任意元素,其实都是根据 myList 纸条去找对应的抽屉去做事,跟 myTuple 没有多大关系,只不过是 myTuple 里面恰巧有一张纸条的数字,跟 myTuple 纸条的数字是一样的。

      左手右手慢动作

      就是常指针呗。

        左手右手慢动作

        觉得可以用函数传递参数的情景解释,
        1.可变对象传引用:可以在原对象上改变,函数内外都持有对该对象的指针,函数内外使用的是一个对象,如果在函数内部改变该对象,函数外部也会改变,类似于引用传递。
        2.不可变对象传拷贝:不可变对象不能在原来的内存空间上变化,所以如果要改变其值,解释器会新建一个对象存放新的变量,这个时候函数内外使用的就不是一个对象了--函数外部还是用的以前的对象,而函数内部已经使用了一个全新的对象。

          Peter_Zhu
          myInt = 5 myList = [3] print id(myList) #id: 37216584 myTuple = (myInt, myList) print myTuple #(5, [3]) myList.append(4) print id(myList) #id: 37216584 print myTuple #(5, [3, 4]) myList = [4, 5] print id(myList)# id: 37258584 print myTuple #(5, [3, 4])

          先确定myList是list对象,指向一个地址(或者说是引用,个人觉得像是一个指针),myTuple存有这个引用。因为是myList可变的,所以可以添加删除,但是它的地址都没变,看先后两次的id。如果将myList指向另一个对象,地址改变了。这时改变的myList不会影响myTuple了。因为Tuple保存的那个list对象没有变化,所以与myTuple无关。

            巴扎黑

            在python中,你这里的myInt也是引用,指向某个整数实体,这跟c/c++不一样,在c/c++中myInt就是整数实体本身了;这样一来,Tuple里存的都是引用,区别只是Int是不可变的,而List是可变的;
            所以你说的矛盾并不存在。

              Neueste Downloads
              Mehr>
              Web-Effekte
              Quellcode der Website
              Website-Materialien
              Frontend-Vorlage
              Über uns Haftungsausschluss Sitemap
              Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!