python 学习笔记(3)-转载
Python中只有一個(gè)賦值模型
一、缺少類型聲明語(yǔ)句的情況
在Python中,類型是在運(yùn)行過(guò)程中自動(dòng)決定的,而不是通過(guò)代碼聲明。這意味著沒(méi)有必要事聲明變量。只要記住,這個(gè)概念實(shí)質(zhì)上對(duì)變量,對(duì)象和它們之間的關(guān)系都適用。那么這個(gè)概念也容易理解并掌握。
1、變量,對(duì)象和引用
變量創(chuàng)建:一個(gè)變量,當(dāng)代碼第一次給它賦值時(shí)它就被創(chuàng)建了。之后的賦值將會(huì)改變已創(chuàng)建的變量名的值。Python在代碼運(yùn)行之前先檢測(cè)變量名,可以當(dāng)成是最初的賦值創(chuàng)建變量。
變量類型:變量永遠(yuǎn)不會(huì)有任何的它關(guān)聯(lián)的類型信息或約束。類型的概念是存在于對(duì)象中而不是變量中。變量原本是通用的。它只是在一個(gè)特定的時(shí)間點(diǎn),簡(jiǎn)單地引用了一個(gè)特定的對(duì)像而已。
變量的使用:當(dāng)變量出現(xiàn)在表達(dá)式中時(shí),它會(huì)馬上被當(dāng)前引用的對(duì)像所代替,無(wú)論這個(gè)對(duì)象是什么類型。
此外,所有的變量都必須在其使用前明確地賦值。使用未賦值的變量會(huì)產(chǎn)生錯(cuò)誤。
>>>a=3
在概念上說(shuō),Python將執(zhí)行三個(gè)不同的步驟去完成這個(gè)請(qǐng)求。
1)、創(chuàng)建一個(gè)對(duì)象來(lái)代表值3
2)、創(chuàng)建一個(gè)變量a,如果它還沒(méi)有創(chuàng)建的話
3)、將變量與新的對(duì)象3連接
在python中從變量到對(duì)象的連接稱作引用。引用是一種關(guān)系,以內(nèi)存中的指針形式實(shí)現(xiàn)。
*變量 是一個(gè)系統(tǒng)表的元素,擁有指向?qū)ο蟮倪B接空間。
*對(duì)象 是被分配的一塊內(nèi)存,有足夠的空間去表現(xiàn)它們所代表的值。
*引用 是自動(dòng)形成的從變量到對(duì)象的指針。
每一個(gè)對(duì)象都用兩個(gè)標(biāo)準(zhǔn)的頭部信息:一個(gè)類型標(biāo)志符去標(biāo)識(shí)這個(gè)對(duì)象的類型,以及一個(gè)引用的計(jì)數(shù)器,用來(lái)決定是不是可以回收這個(gè)對(duì)象。
2、類型屬于對(duì)象,而不是變量
Python中的類型是與對(duì)象相關(guān)聯(lián)的,而不是和變量關(guān)聯(lián)。
變量沒(méi)有類型,變量指向?qū)ο蟆?duì)象有類型,知道自己的類型,每個(gè)對(duì)象都包含了一個(gè)頭部信息,其中標(biāo)記了這個(gè)對(duì)象的類型。
3、對(duì)象的垃圾收集
對(duì)象生命結(jié)束時(shí)發(fā)生了什么變化?
每當(dāng)一個(gè)變量名被賦與了一個(gè)新的對(duì)象,之前的那個(gè)對(duì)象占用的空間就會(huì)被收回(如果它沒(méi)有被其他變量名和對(duì)象所引用).這種自動(dòng)回收對(duì)象空間的技術(shù)稱作垃圾收集。
在內(nèi)部,Python是通過(guò)保持用每個(gè)對(duì)象中的計(jì)數(shù)器記錄引用指到這個(gè)對(duì)象上的次數(shù)來(lái)完成這一功能。一旦(并精確在同一時(shí)間)這個(gè)計(jì)數(shù)器被設(shè)置為零,這個(gè)對(duì)象的內(nèi)存空間就會(huì)自動(dòng)收回。垃圾收集最直接的,可感受到的好處就是這意味著可以在腳本中任意使用對(duì)象而不需要考慮釋放內(nèi)存空間。
>>> x=42
>>> id(x)
674748828
>>> x="diege"
>>> id(x)????
676367648
二、共享引用
上面所講都是單個(gè)變量被賦值引用了多個(gè)對(duì)象的情況。現(xiàn)在,在交互模式下,引入另一個(gè)變量,并看一下變量名和對(duì)象的變化。
>>> a=10
>>> b=a?
>>> id(a)
674749212
>>> id(b)
674749212
第二行會(huì)使用python創(chuàng)建變量b。使用的是變量a,并且它在這里沒(méi)有被賦值,所以它被替換成其應(yīng)用的對(duì)象10,從而b也成為這個(gè)對(duì)象的一個(gè)引用。實(shí)際效果就是變量a和b都引用相同的對(duì)象(也就是說(shuō)指向了相同的內(nèi)存空間。在Python中稱作是共享引用--多個(gè)變量名應(yīng)用了同一個(gè)對(duì)象。)
>>> a=10?
>>> b=a??
>>> a='diege'
>>> id(a)?
676367648
>>> id(b)
674749212
變量a改變了,但是不影響變量b.這完全可以說(shuō)明變量b是指向?qū)ο?0內(nèi)存空間的。
在ptyhon中,變量總是一個(gè)指向?qū)ο蟮闹羔?#xff0c;而不是可以改變的內(nèi)存區(qū)域的標(biāo)簽。給一變量賦一個(gè)新的值,并不是替換了原始的對(duì)象,而是讓這個(gè)變量去引用完全不同的一個(gè)對(duì)象。實(shí)際的效果就是對(duì)一個(gè)變量賦值,僅僅會(huì)影響那個(gè)被賦值的變量。
1、共享引用和在原處修改
有一些對(duì)象和類型確實(shí)會(huì)在實(shí)地改變對(duì)象。例如,在一個(gè)列表中對(duì)一個(gè)偏移進(jìn)行賦值確實(shí)會(huì)改變這個(gè)列表對(duì)象,而不是生成一個(gè)新的列表對(duì)象。
>>> T1=[11,12,13]
>>> T2=T1
>>> T1
[11, 12, 13]
>>> T2
[11, 12, 13]
>>> T1=22
>>> T1
22
>>> T2
[11, 12, 13]
這個(gè)和先前一樣T1改變了T2沒(méi)有改變,T2改變也不影響T1
>>> T1=[11,12,13]
>>> T2=T1
>>> T1
[11, 12, 13]
>>> T2
[11, 12, 13]
>>> T2[1]=33?????
>>> T1
[33, 12, 13]
>>> T2
[33, 12, 13]
發(fā)現(xiàn)T2改變了,T1也跟這改變了.
同樣T1改變了,T2也改變了
>>> T1[1]=99??
>>> T2
[33, 99, 13]
>>> T1
[33, 99, 13]
這里T1沒(méi)有改變,改變了T1所引用對(duì)象的一個(gè)元素。這類修改會(huì)覆蓋列表對(duì)象中的某部分。因?yàn)檫@個(gè)列表對(duì)象是與其他對(duì)象共享的(被其他對(duì)象引用),那么一個(gè)像這樣在原處的改變不僅僅會(huì)對(duì)T1有影響。必須意識(shí)到當(dāng)做了這樣的修改,它會(huì)影響程序的其他部分。
如果不想要這樣的現(xiàn)象發(fā)生,需要Python拷貝對(duì)象,而不是創(chuàng)建引用。方法包括內(nèi)置列表函數(shù)以及標(biāo)準(zhǔn)庫(kù)的copy模塊,最常用的辦法就是從頭到尾的分片T1[:]
>>> T1=[11,12,13]
>>> T2=T1[:]
>>> T1
[11, 12, 13]
>>> T2
[11, 12, 13]
>>> T1[0]=99
>>> T1
[99, 12, 13]
>>> T2
[11, 12, 13]
>>> id(T1)
676366604
>>> id(T2)
675542060
T1和T2指向不同的對(duì)象,所以不會(huì)相互影響。
注意:這種分片技術(shù)不會(huì)引用在其他的可變的核心類型上(字典,因?yàn)樗鼈儾皇切蛄?#xff09;,對(duì)字典應(yīng)該使用D.copy()方法.而且,注意標(biāo)準(zhǔn)庫(kù)中的copy模塊有一個(gè)通用的拷貝任意對(duì)象的調(diào)用,也有一個(gè)拷貝嵌套對(duì)象的結(jié)構(gòu)的調(diào)用.
>>> X={'name':'diege','age':28}??
>>> import copy
>>> Y=copy.copy(X)
>>> X
{'age': 28, 'name': 'diege'}
>>> Y
{'age': 28, 'name': 'diege'}
>>> id(X)
676370468
>>> id(Y)
676414436
>>> X={'name':{'FirstName':'diege','LastName':'wangkaijin'},'age':28}????
>>> X
{'age': 28, 'name': {'LastName': 'wangkaijin', 'FirstName': 'diege'}}
>>> Y=copy.copy(X)
>>> Y
{'age': 28, 'name': {'LastName': 'wangkaijin', 'FirstName': 'diege'}}
>>> Z=copy.deepcopy(X)?
>>> Z
{'age': 28, 'name': {'LastName': 'wangkaijin', 'FirstName': 'diege'}}
2、共享引用和相等
>>> x=33
>>> x='diege'
因?yàn)镻ython緩存并復(fù)用了小的整數(shù)和小的字符串,就像前文提到的那樣,這里對(duì)象33也許不像前期所說(shuō)的被收回,相反,它將可能仍保持在一個(gè)系統(tǒng)表中,等待下一次你的代碼生成另一個(gè)33來(lái)利用。盡快如此,大多數(shù)種類的對(duì)象都會(huì)在不再引用時(shí)馬上回收。對(duì)于那些不會(huì)被回收的,緩沖機(jī)制與代碼并沒(méi)有什么關(guān)系。
判斷是否相等
>>> L=[1,2,3]
>>> M=L
>>> L==M
True
>>> L is M
True
==檢查對(duì)象是否有相同的值。 is操作符,檢查對(duì)象的同一性。如果兩個(gè)變量名精準(zhǔn)地指向同一個(gè)對(duì)象,它會(huì)返回True。所以這是一種更嚴(yán)格的相等測(cè)試。
實(shí)際上,is只是比較現(xiàn)實(shí)引用的指針。所以如果必要的話是代碼中檢測(cè)共享引用的一種方法。如果變量名引用值相等。但是為不同的對(duì)象,它的返回值將是False.
>>> L=[1,2,3]
>>> M=[1,2,3]
>>> L==M
True
>>> L is M
False
>>> id(L)
676367788
>>> id(M)
676367724
通過(guò)id()函數(shù)可以看到兩個(gè)變量指向不同的對(duì)象。
>>> X=33
>>> Y=33
>>> X==Y
True
>>> X is Y
True
>>> id(X)
674748936
>>> id(Y)
674748936
這個(gè)is測(cè)試返回True因?yàn)樾〉恼麛?shù)和字符串被緩存被復(fù)用了。
如果想更進(jìn)一步了解,可以向Python查詢一個(gè)對(duì)象應(yīng)用的次數(shù):在sys模塊中的getrefcount函數(shù)返回對(duì)象應(yīng)用的次數(shù)。
>>> import sys
>>> sys.getrefcount(33)
13
>>> sys.getrefcount(1)?
427
>>> sys.getrefcount(00)
296
>>> sys.getrefcount(99)
6
本文出自 “diege” 博客,請(qǐng)務(wù)必保留此出處http://ipseek.blog.51cto.com/1041109/786518
轉(zhuǎn)載于:https://blog.51cto.com/searchina/1621151
總結(jié)
以上是生活随笔為你收集整理的python 学习笔记(3)-转载的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 敏捷个人新体系学习 - 2.定位
- 下一篇: solaris10找安装包的地方