最近在研究某一博主的代碼時偶然發(fā)現(xiàn)了一個問題,第一反應(yīng)肯定是我自己知識上的欠缺。然后經(jīng)過各種百度啊之類的終于找到了原因。
我們提供的服務(wù)有:成都做網(wǎng)站、網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、沛縣ssl等。為1000+企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的沛縣網(wǎng)站制作公司
上面就是我遇到的問題,按照我的理解,featLabel這個列表經(jīng)過函數(shù)調(diào)用后值應(yīng)該還是空的,如果普通的參數(shù),我的這種理解是完全正確的,但是為什么列表featLabel會跟著改變呢?于是我聯(lián)想到了java里面的像String這種引用數(shù)據(jù)類型,貌似他們有幾分相似之處。好了,問題說到這,接下來說一下問題的解決。
在python中的數(shù)據(jù)可以分為可變數(shù)據(jù)類型和不變數(shù)據(jù)類型。
可變數(shù)據(jù)類型:
像tuple,list,dict之類的變量就是可變數(shù)據(jù)類型,變量名存儲的是一個地址,該地址指向一個具體的對象,并且不管對變量的值即對象做怎么樣的操作,都不會改變變量名存儲的地址。下面是一個例子:
def?fun(labels):
dic?=?[1,?2,?3]
labels.append(dic)
print(id(labels))
return?dic
if?__name__?==?'__main__':
labels?=?['hello']
my?=?fun(labels)
print(labels,?'\n',?id(labels))
結(jié)果如下:
['hello', [1, 2, 3]]
39593224
可見,我們把列表作為參數(shù)傳入一個函數(shù)時,在函數(shù)內(nèi)我們對該列表進行了一些改變,由于變量存儲的地址沒有變(在函數(shù)內(nèi)部和函數(shù)外部都是39593224),所以就算我們沒有故意通過return語句把該列表傳遞出來,該列表還是會在函數(shù)執(zhí)行結(jié)束后跟著改變的。
不變數(shù)據(jù)類型:
不變數(shù)據(jù)類型的對象一旦發(fā)生改變,就會在內(nèi)存中開辟一個新的空間用于存儲新的對象,原來的變量名就會指向一個新的地址。舉個例子:
def?fun(labels):
labels?=?'world'
print(id(labels))
if?__name__?==?'__main__':
labels?=?'hello'
fun(labels)
print(labels,?'\n',?id(labels))
結(jié)果如下:
38578360
hello
39220984
樓上說的很好,初學(xué)小白的我也想到了同樣的問題。按照樓上的提示我搜索了不可變對象與可變對象,參考該篇博文摘取部分網(wǎng)頁鏈接網(wǎng)頁鏈接
python中,對象分為可變(mutable)和不可變(immutable)兩種類型,元組(tuple)、數(shù)值型(number)、字符串(string)均為不可變對象,而字典型(dictionary)和列表型(list)的對象是可變對象。
所謂可變對象是所謂可變對象是指,對象的內(nèi)容可變,而不可變對象是指對象內(nèi)容不可變。
題目中l(wèi)是列表變量,為可變變量,每次調(diào)用函數(shù)可以改變該對象的內(nèi)容;而題中的s為字符串變量,是不可變對象,調(diào)用了字符串操作函數(shù)lstrip()只會生成一個拷貝,對拷貝去除空格,而變量s本身不發(fā)生改變。
在Python中,對這兩個東西有明確的規(guī)定:
函數(shù)function —— A series of statements which returns some value to a caller. It can also be passed zero or more arguments which may be used in the execution of the body.
方法method —— A function which is defined inside a class body. If called as an attribute of an instance of that class, the method will get the instance object as its first argument (which is usually called self).
從定義的角度上看,我們知道函數(shù)(function)就相當于一個數(shù)學(xué)公式,它理論上不與其它東西關(guān)系,它只需要相關(guān)的參數(shù)就可以。所以普通的在module中定義的稱謂函數(shù)是很有道理的。
那么方法的意思就很明確了,它是與某個對象相互關(guān)聯(lián)的,也就是說它的實現(xiàn)與某個對象有關(guān)聯(lián)關(guān)系。這就是方法。雖然它的定義方式和函數(shù)是一樣的。也就是說,在Class定義的函數(shù)就是方法。
從上面的角度看似乎很有道理。
def fun():
pass
type(fun)
class 'function' #沒有問題
class Cla():
def fun():
pass
@classmethod
def fun1(cls):
pass
@staticmethod
def fun2():
pass
i=Cla()
Cla.fun.__class__
class 'function' #為什么還是函數(shù)
i.fun.__class__ #這個還像話
class 'method'
type(Cla.fun1)
class 'method' #這里又是方法
type(i.fun1)
class 'method'#這里仍然是方法
type(Cla.fun2)
class 'function' #這里卻是函數(shù)
type(i.fun2)
class 'function'#這里卻是函數(shù)
事實上,上面的結(jié)果是可以解釋的:
1,普通方法(老版中直接就是"instancemethod")在module中與在Class中定義的普通函數(shù),從其本身而言是沒有什么區(qū)別的,他們都是對象函數(shù)屬性。 之所以會被說在Class中的定義的函數(shù)被稱為方法,是因為它本來就是面向?qū)淼膶嵗龑ο蟮模鋵嵥麄兙褪菍嵗椒?,這些方法是與實例相聯(lián)系的(從實例出發(fā)訪問該函數(shù)會自動賦值)。所以你從Class訪問仍然是一個函數(shù)
2,類方法("classmethod"),因為類同樣是對象,所以如果函數(shù)與類進行聯(lián)系了話(與實例方法一樣的模式)那么就能夠這么說了!
3,靜態(tài)方法,雖然定義在內(nèi)部,并且也較方法,但是卻不與任何對象聯(lián)系,與從類訪問方法是一樣的,他們?nèi)匀皇呛瘮?shù)。
這樣看來上面的定義可以改改了:
函數(shù)的定義自然不變。
方法的定義可以是這樣的,與某個對象進行綁定使用的函數(shù)。注意哦。綁定不是指" . "這個符號,這個符號說實在的只有域名的作用。綁定在這里是指,會默認賦值該綁定的對象。
這里改一下:
if len(x)!=11:
print('你的號碼不足11位,無效!')
x=tel_number() #這里如果不改x的值還是151
return x
當前名稱:函數(shù)變與不變python 函數(shù)不變值
分享URL:http://sd-ha.com/article14/doocjde.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、移動網(wǎng)站建設(shè)、搜索引擎優(yōu)化、電子商務(wù)、網(wǎng)站導(dǎo)航、定制開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)