亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        從零學python之引用和類屬性的初步理解

        字號:


            python是一種解釋型、面向對象、動態(tài)數據類型的高級程序設計語言。自從20世紀90年代初python語言誕生至今,它逐漸被廣泛應用于處理系統(tǒng)管理任務和web編程。python已經成為最受歡迎的程序設計語言之一。2011年1月,它被tiobe編程語言排行榜評為2010年度語言。自從2004年以后,python的使用率是呈線性增長。
            python在設計上堅持了清晰劃一的風格,這使得python成為一門易讀、易維護,并且被大量用戶所歡迎的、用途廣泛的語言。
            鑒于以上各種優(yōu)點,忍不住對python進行了一番學習,略有收獲,分享給大家。
            最近對python的對象引用機制稍微研究了一下,留下筆記,以供查閱。
            首先有一點是明確的:「python中一切皆對象」。
            那么,這到底意味著什么呢?
            如下代碼:
            代碼如下:
            #!/usr/bin/envpython
            a=[0,1,2]#來個簡單的list
            #最初,list和其中各個元素的id是這樣的。
            print'origin'
            printid(a),a
            forxina:
            printid(x),x
            print'----------------------'
            #我們把第一個元素改改
            print'afterchangea[0]'
            a[0]=4
            printid(a),a
            forxina:
            printid(x),x
            print'----------------------'
            #我們再把第二個元素改改
            print'afterchangea[1]'
            a[1]=5
            printid(a),a
            forxina:
            printid(x),x
            print'----------------------'
            #回頭看看直接寫個0,id是多少
            print'howaboutconst0?'
            printid(0),0
            運行結果如下:
            代碼如下:
            pastgiftmacbookpro:pythonpastgift$./reftest.py
            origin
            [0,1,2]
            0
            1
            2
            ----------------------
            afterchangea[0]
            [4,1,2]
            4
            1
            2
            ----------------------
            afterchangea[1]
            [4,5,2]
            4
            5
            2
            ----------------------
            howaboutconst0?
            0
            從「origin」部分來看,list中各個元素的地址之間都正好相差24,依次指向各自的數據——這讓我想到了數組。
            當修改a[0]的值之后,發(fā)現,a[0]的地址發(fā)生了變化。也就是說,賦值語句實際上只是讓a[0]重新指向另一個對象而已。此外,還注意到,a[0]的地址和a[2]的地址相差48(2個24)。
            當再次修改a[1]之后,同樣地,a[1]的地址也發(fā)生變化,有趣的是,這次a[1]的地址和a[0]的地址又相差24,和原先的a[2]相差72(3個24)。
            最后,當直接把數字0的地址打印出來后,發(fā)現它的地址和最開始的a[0]的地址完全一樣。
            至此,基本可以說明,就算是list中的元素,其實也是引用。修改list中的元素,實際上還是在修改引用而已。
            對于python中類屬性,有人提到過「類屬性在同一類及其子類之間共享,修改類屬性會影響到同一類及其子類的所有對象」。
            聽著挺嚇人,但仔細研究之后,其實倒也不是什么大不了的事情。
            如下代碼:
            代碼如下:
            #!/usr/bin/envpython
            classbird(object):
            name='bird'
            talent=['fly']
            classchicken(bird):
            pass
            bird=bird();
            bird2=bird();#同類實例
            chicken=chicken();#子類實例
            #最開始是這樣的
            print'originalattr'
            printid(bird.name),bird.name
            printid(bird.talent),bird.talent
            printid(bird2.name),bird2.name
            printid(bird2.talent),bird2.talent
            printid(chicken.name),chicken.name
            printid(chicken.talent),chicken.talent
            print'----------------------------'
            #換個名字看看
            bird.name='birdnamechanged!'
            print'afterchangingname'
            printid(bird.name),bird.name
            printid(bird.talent),bird.talent
            printid(bird2.name),bird2.name
            printid(bird2.talent),bird2.talent
            printid(chicken.name),chicken.name
            printid(chicken.talent),chicken.talent
            print'----------------------------'
            #洗個天賦試試(修改類屬性中的元素)
            bird.talent[0]='walk'
            print'afterchangingtalent(alist)'
            printid(bird.name),bird.name
            printid(bird.talent),bird.talent
            printid(bird2.name),bird2.name
            printid(bird2.talent),bird2.talent
            printid(chicken.name),chicken.name
            printid(chicken.talent),chicken.talent
            print'----------------------------'
            #換個新天賦樹(整個類屬性全換掉)
            bird.talent=['swim']
            print'afterreassigntalent'
            printid(bird.name),bird.name
            printid(bird.talent),bird.talent
            printid(bird2.name),bird2.name
            printid(bird2.talent),bird2.talent
            printid(chicken.name),chicken.name
            printid(chicken.talent),chicken.talent
            print'----------------------------'
            #洗掉新天賦樹(對新來的類屬性中的元素進行修改)
            bird.talent[0]='dance'
            print'changingelementafterreassigningtalent'
            printid(bird.name),bird.name
            printid(bird.talent),bird.talent
            printid(bird2.name),bird2.name
            printid(bird2.talent),bird2.talent
            printid(chicken.name),chicken.name
            printid(chicken.talent),chicken.talent
            print'----------------------------'
            運行結果:
            代碼如下:
            pastgiftmacbookpro:pythonpastgift$./changeattributetest.py
            originalattr
            bird
            ['fly']
            bird
            ['fly']
            bird
            ['fly']
            ----------------------------
            afterchangingname
            birdnamechanged!
            ['fly']
            bird
            ['fly']
            bird
            ['fly']
            ----------------------------
            afterchangingtalent(alist)
            birdnamechanged!
            ['walk']
            bird
            ['walk']
            bird
            ['walk']
            ----------------------------
            afterreassigntalent
            birdnamechanged!
            ['swim']
            bird
            ['walk']
            bird
            ['walk']
            ----------------------------
            changingelementafterreassigningtalent
            birdnamechanged!
            ['dance']
            bird
            ['walk']
            bird
            ['walk']
            ----------------------------
            在「origin」的時候,同類對象,子類對象的相同類屬性的地址都是相同的——這就是所謂的「共享」。
            修改name之后,只有被修改的對象name屬性發(fā)生變化。這是因為對name的賦值操作實際上就是換了一個字符串,重新引用。字符串本身并沒有發(fā)生變化。所以并沒有在同類和子類之間產生互相影響。
            接下來,修改talent中的元素。這時,情況有所改變:同類及其子類的talent屬性都一起跟著變了——這很好理解,因為它們都引用的內存地址都一樣,引用的是同一個對象。
            再接下來,給talent重新賦值,也就是改成引用另外一個對象。結果是只有本實例的talent屬性變化了。從內存地址可以看出,本實例和其他實例的talent屬性已經不再指向相同的對象了。就是說「至此,本實例已經是圈外人士了」。
            那么,最后再次修改talent中元素后,對其他實例無影響的結果也是很好理解了。因為已經是「圈外人士」了嘛,我再怎么折騰也都是自己的事情了。
            所以,「類屬性在同類及其子類之間互相影響」必須有一個前提條件:實例建立后,其類屬性從來沒有被重新賦值過,即類屬性依然指向最初所指向的內存地址。
            最后提一下對象屬性
            如下代碼:
            代碼如下:
            #!/usr/bin/envpython
            classbird(object):
            def__init__(self):
            self.talent=['fly']
            bird=bird()
            bird2=bird()
            #剛開始的情形
            print'origin'
            printid(bird.talent),bird.talent
            printid(bird2.talent),bird2.talent
            print'--------------------'
            #修改其中一個對象的屬性
            bird.talent[0]='walk'
            print'afterchangingattribute'
            printid(bird.talent),bird.talent
            printid(bird2.talent),bird2.talent
            print'--------------------'
            #作死:兩個對象的屬性指向同一個內存地址,再修改
            bird.talent=bird2.talent
            bird.talent[0]='swim'
            print'assigntoanotherattributeandchangeit'
            printid(bird.talent),bird.talent
            printid(bird2.talent),bird2.talent
            print'--------------------'
            運行結果:
            代碼如下:
            pastgiftmacbookpro:pythonpastgift$./changeattributetest2.py
            origin
            ['fly']
            ['fly']
            --------------------
            afterchangingattribute
            ['walk']
            ['fly']
            --------------------
            assigntoanotherattributeandchangeit
            ['swim']
            ['swim']
            --------------------
            由于對象屬性就算內容完全一樣(剛初始化后的屬性內容一般都是一樣的),也會分配到完全不同的內存地址上去。所以不存在「同類對象之間影響」的情況。
            但如果讓一個對象的屬性和另一個對象的屬性指向同一個地址,兩者之間(但也僅限兩者之間)便又互相牽連起來。