對(duì)于Python的初學(xué)者,在對(duì)象的使用過(guò)程中,由于對(duì)變量的賦值和對(duì)象的復(fù)制中的概念模糊,導(dǎo)致程序出錯(cuò)。
成都創(chuàng)新互聯(lián)主要從事網(wǎng)站建設(shè)、成都網(wǎng)站制作、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)嵊州,十載網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢(xún)建站服務(wù):13518219792
例如,下面的代碼:
輸出結(jié)果為:
a = [6,2,3,4,5],
b = [6,2,3,4,5],
c = [1,2,3,4,5]
a等于b?True
a等于c?True
a是b?True
a是c? False
可以看到,a,b, c所指向的對(duì)象的值都相同(a==b為T(mén)rue). a和b都是代表同一個(gè)對(duì)象(a is b為T(mén)rue)。當(dāng)我們通過(guò)變量b對(duì)該列表進(jìn)行修改時(shí),由于a也指向該列表,所以當(dāng)打印a,b時(shí),我們得到相同的值。 而a和c則是代表不同的對(duì)象(a is c為False),所以修改b所指向得列表不會(huì)改變c梭子鄉(xiāng)的列表的值.
在Python中,所有的變量都代表了對(duì)象,即便是簡(jiǎn)單的數(shù)字類(lèi)型(int, float, bool),也是以對(duì)象的形式存在的。我們看下面的代碼:
輸出結(jié)果是:
a==b為T(mén)rue
a is b為T(mén)rue
可見(jiàn),a, b都是指向同一個(gè)對(duì)象。接下來(lái),進(jìn)行下面的操作,
輸出結(jié)果是:
a = 1, b = 2
a is b為False
與前面的列表不同,當(dāng)我們對(duì)b做修改時(shí),實(shí)際上是給b賦予了一個(gè)新生成的對(duì)象,對(duì)數(shù)值類(lèi)型來(lái)說(shuō),所有的數(shù)值運(yùn)算都會(huì)創(chuàng)建一個(gè)數(shù)值對(duì)象,并將這個(gè)對(duì)象指定給變量。因此,a與b指向了不同的對(duì)象,數(shù)值也不同。
再回過(guò)頭來(lái)看列表對(duì)象,
我們知道,b是與a指向同一對(duì)象的變量,使用b對(duì)該對(duì)象進(jìn)行修改,與使用a對(duì)該對(duì)象進(jìn)行修改,效果是完全一樣的。如果我們需要需要一個(gè)與a完全相同又與a相互獨(dú)立的列表,那么就需要復(fù)制這個(gè)對(duì)象,也就是新建一個(gè)內(nèi)容和源對(duì)象相同的對(duì)象。
對(duì)于列表來(lái)說(shuō),最簡(jiǎn)單的復(fù)制方法是通過(guò)下標(biāo)索引的方式創(chuàng)建新的列表:
對(duì)于各種數(shù)據(jù)類(lèi)型通用的對(duì)象拷貝復(fù)制,我們可以使用python內(nèi)建的copy模塊。
對(duì)于復(fù)雜對(duì)象(如嵌套列表)的復(fù)制,則需要注意區(qū)分淺拷貝和深拷貝。我們來(lái)看下面的代碼:
得到的結(jié)果是:
a[0] is b[0]為 True
a[0] is c[0]為 False
a = [[-1, 2, 3], [4, 5, 6]]
b = [[-1, 2, 3], [7, 8, 9]]
c = [[1, 2, 3], [4, 5, 6]]
a[1] is b[1]為False
從上面的代碼我們可以看到,copy函數(shù)為淺拷貝,只拷貝了對(duì)象的外層,而對(duì)象內(nèi)部所包含的對(duì)象仍然指向原有的對(duì)象。而deepcopy則為深拷貝,對(duì)象內(nèi)部的對(duì)象也進(jìn)行了復(fù)制。
以上我們對(duì)變量的賦值和對(duì)象的復(fù)制做了更加深入的分析。在具體的使用中,我們需要根據(jù)具體來(lái)決定使用賦值、淺拷貝、深拷貝。
params
就是(5, 5)
(5,) * 2 ,就是2個(gè)5的元組,乘號(hào)可以理解成相加。"*" * 30就是30個(gè)“*"的字符串
*params作為參數(shù),前面的*號(hào)就是把params元組分解成元素的意思,這樣就分開(kāi)成為2個(gè)參數(shù)了。實(shí)際上傳遞給了x,y
于是就執(zhí)行了power(5,5)
在python中,變量賦值的語(yǔ)法比較簡(jiǎn)單,語(yǔ)法就是 “變量名 = 對(duì)象”,由于python屬于動(dòng)態(tài)語(yǔ)音,所以不需要像c、 java那樣在變量賦值時(shí)需要聲明變量的類(lèi)型。
c 變量賦值
int x = 1;
python 變量賦值
x = 1
y = "hello world!"
a = [1, 2]
b = ('a', 'b')
c = {"foo": "bar"}
python 變量賦值中,所涉及到的變量命名是有一定規(guī)則的:
1. 變量名只能包含字母、數(shù)字和下劃線(xiàn)。變量名可以字母或下劃線(xiàn)開(kāi)頭,但不能以數(shù)字開(kāi)頭,例如,可將變量命名為name_1,但不能將其命名為1_name
2.?變量名不能包含空格,但可使用下劃線(xiàn)來(lái)分隔其中的單詞。例如,變量名name_one可行,但變量名name one會(huì)引發(fā)錯(cuò)誤。
3.?不要將Python關(guān)鍵字和函數(shù)名用作變量名,即不要使用Python保留用于特殊用途的單詞,如not、pass等。
4.?變量名應(yīng)既簡(jiǎn)短又具有描述性。例如,name比n好,student_name比s_n好,name_length比length_of_persons_name好, 雖說(shuō)簡(jiǎn)短好,但是不能依照自己的意愿隨意簡(jiǎn)寫(xiě),盡量使用大家約定俗成的簡(jiǎn)寫(xiě),如果不是還不如寫(xiě)全拼。
5. python 變量名中大小寫(xiě)敏感,所以 NAME, Name, name 代表三個(gè)不同的表里名, 這里提一下就是慎用小寫(xiě)字母l和大寫(xiě)字母O,因給他們可能被人錯(cuò)看成數(shù)字1和0;
再說(shuō)變量賦值中賦予給變量的值,python中萬(wàn)事皆對(duì)象,所以python中只要是對(duì)象就能給變量賦值。如:
x = 1 # x賦值為數(shù)字1;
x = sum # x賦值為內(nèi)建求和函數(shù)sum;
python的賦值真實(shí)上說(shuō)應(yīng)該不是賦值,而更像是“引用”,如何理解“引用”呢,python中一直對(duì)象的生成是會(huì)在內(nèi)存中分配給一個(gè)內(nèi)存地址,這個(gè)內(nèi)存地址可以使用id()方法去獲取,然后在變量賦值時(shí),將變量直接引用該對(duì)象的內(nèi)存地址,進(jìn)而完成變量賦值,如:
x = 1, 賦值時(shí)x直接引用1所在內(nèi)存的地址, y = x, 此時(shí)是y直接引用x的所指向的內(nèi)存地址
python中有判斷變量的方法如 is() 和 ==,二者在判斷變量時(shí)是有區(qū)別的,is函數(shù)是判斷變量的內(nèi)存地址是否相同,而 == 是判斷變量的值是否相同,舉例說(shuō)明:
a = 1; b = 1.0
a is b? # False
a == b # True
小心python變量賦值的陷阱
看到上面的所述知道了python變量賦值實(shí)則是引用,引用的是對(duì)象的內(nèi)存地址。所賦的值可以分兩類(lèi),一類(lèi)是可變的,如列表,字典,集合;一類(lèi)是不可變的,如字符串、元組。所以當(dāng)對(duì)象為可變類(lèi)型時(shí)就會(huì)出現(xiàn)一種情景,我們舉例說(shuō)明:
x = [1, 2, 3]
y = x
print x == y? ? # True
print x is y? ? # True
print x? ? ?# [1, 2, 3]
print y? ? ?# [1, 2, 3]
y.append(4)
print x? ? # [1, 2, 3, 4]
print y? ? # [1, 2, 3, 4]
可以看到y(tǒng)在進(jìn)行調(diào)整時(shí)(添加了一個(gè)元素),x也跟著變動(dòng)了,這進(jìn)一步說(shuō)明了,python中的變量賦值時(shí)引用,x,y 賦值時(shí)指向了同一處內(nèi)存地址,所以當(dāng)y變動(dòng)時(shí),x同樣也發(fā)送了變化,解決這中現(xiàn)象的方法可以是x, y = [1,2,3], [1,2,3]這樣賦值,雖說(shuō)此時(shí) x==y 是True,但是確實(shí)是2個(gè)不同的內(nèi)存地址,所以 x is y 則是 False?;蛘呖梢允褂胏opy模塊,實(shí)質(zhì)是相同的,創(chuàng)建2個(gè)不同的內(nèi)存地址,使其分離。
Python中的賦值是一種語(yǔ)句,是將創(chuàng)建的一個(gè)數(shù)據(jù)對(duì)象,然后通過(guò)變量對(duì)這個(gè)值進(jìn)行引用,變量即代表這個(gè)值,后面對(duì)這個(gè)數(shù)據(jù)的操作都通過(guò)這個(gè)變量來(lái)完成,這就是賦值。
Python的自定義函數(shù)格式中規(guī)中矩,用def引導(dǎo)自定義函數(shù)名,用括號(hào)給出該函數(shù)的參數(shù),在冒號(hào)后換行通過(guò)縮進(jìn)確定函數(shù)體。在格式上和條件判斷語(yǔ)句有些相似。
如果函數(shù)名和變量名沖突了,相當(dāng)于重新賦值。而python解釋是從上到下的,也就是說(shuō)此時(shí)誰(shuí)在下面誰(shuí)占用這個(gè)變量名。剩下的那個(gè)就只能在內(nèi)存中等待垃圾回收了。
自定義函數(shù)的參數(shù):
按道理來(lái)說(shuō),即使Python不嚴(yán)格要求定義函數(shù)參數(shù),但這方面的知識(shí)有助于理解自定義函數(shù)中參數(shù)操作的情況,還是應(yīng)該說(shuō)明一下的。
可以簡(jiǎn)單地理解為在定義函數(shù)時(shí)括號(hào)中聲明的參數(shù)是我們?cè)诤瘮?shù)使用中會(huì)用到的參數(shù),在調(diào)用函數(shù)時(shí)括號(hào)中的變量就是參加函數(shù)運(yùn)算用到的變量,換個(gè)名字參數(shù)(用于定義)和變量(用于調(diào)用)就足以理解了。