python实例属性与类属性_Python中的类属性和实例属性引发的一个坑-续
上篇文章Python 中的類屬性和實(shí)例屬性,我們探討了類屬性和實(shí)例屬性引發(fā)的一個小坑。總結(jié)了類屬性和實(shí)例屬性的區(qū)別如下:類屬性可以被類和實(shí)例調(diào)用,實(shí)例屬性只能被實(shí)例調(diào)用
類屬性不會隨著實(shí)例的調(diào)用而改變
類屬性的有效作用域只有類,實(shí)例屬性的有效作用域只有本實(shí)例(有效作用域并非官方描述,而是我做的一個類比,大家可與作用域類別)。
其實(shí)第二點(diǎn)可以忽略,第三點(diǎn)已經(jīng)涵蓋了。我把文章發(fā)給了小伙伴們品讀,有小伙伴針對第二三條提出了不同的看法。看如下例子:
class Persion(object):
count = 0
info = {
'name': '小明'
}
info_list = []
def __init__(self):
self.name = '人'
if __name__ == '__main__':
p = Persion()
p.count = 5
print(p.count) # 5
print(Persion.count) # 0
p.count += 5
print(p.count) # 10
print(Persion.count) # 0
p.info['name'] = '小紅'
print(p.info) # {'name': '小紅'}
print(Persion.info) # {'name': '小紅'}
p2 = Persion()
p2.info = {'name': 'Tom'}
print(p2.info) # {'name': 'Tom'}
print(Persion.info) # {'name': '小紅'}
實(shí)例中,info 的值被修改了,那么是否可以說「實(shí)例可以修改類屬性」了呢?我們來繼續(xù)分析,來看 count 和 info 區(qū)別,不難想到它們一個是「不可變變量(immutable type)」,一個是「可變變量(mutable type)」,這兩種變量類型的區(qū)別在于內(nèi)存的使用。
Python 變量中實(shí)際上保存的是內(nèi)存中值的引用,「不可變變量」修改時,是改變了引用,「可變變量」修改時,是改變了內(nèi)存塊中的值。如下:不可變變量
i = 20
j = 20
print(id(i)) # 4299177184
print(id(j)) # 4299177184 不同變量引用了同一個值
i +=1
print(id(i)) # 4340788480 值變了,變量的引用地址也變了可變變量
d1 = [1, 2, 3]
d2 = [1, 2, 3]
print(id(d1)) # 4514412936
print(id(d2)) # 4511850248 # 相同值,變量的引用地址不同
d1.append(4)
print(id(d1)) # 4514412936 # 值變了,變量的引用地址沒變
說回我們討論的問題,當(dāng)修改 info 的name key 所對應(yīng)的值時,實(shí)際上是修改了內(nèi)存塊中的值,因?yàn)閷?shí)例p和類Person的 info 屬性都是指向了統(tǒng)一內(nèi)存地址,所以類Person的 info 屬性的值也變了。而當(dāng)我們直接給實(shí)例p的 info 屬性賦值時,它引用的是另一個內(nèi)存地址的值,雖然值和類Person的 info 相同,但是引用不同,所以當(dāng)p的屬性修改時,Person的 info 屬性沒有變化的。
那我們來總結(jié)一下:當(dāng)類的屬性為不可變變量時,實(shí)例屬性是對類屬性值的引用,修改實(shí)例屬性僅僅是修改了引用,不會修改原來的值,即不會修改類屬性。
當(dāng)類的屬性為可變變量時,分下面兩種情況:當(dāng)直接修改實(shí)例屬性時,因?yàn)槭强勺冏兞?#xff0c;即把內(nèi)存中的值修改了,所以類屬性的值也修改了。
當(dāng)重新賦值實(shí)例屬性時,因?yàn)楹皖悓傩缘囊貌煌?#xff0c;即使值改變了,也不會影響類屬性的值。
那么上篇中結(jié)論有些不太嚴(yán)謹(jǐn),需要針對「可變變量」和「不可變變量」做些區(qū)分,這里有些類似函數(shù)傳參時的作用域的關(guān)系。大家在實(shí)際應(yīng)用中,一定要注意「可變變量」和「不可變變量」的區(qū)別。
更多「可變變量」和「不可變變量」資料可參閱:How do I pass a variable by reference?[1]
Facts and Myths about Python names and values[2]
參考資料
[2] Facts and Myths about Python names and values:
總結(jié)
以上是生活随笔為你收集整理的python实例属性与类属性_Python中的类属性和实例属性引发的一个坑-续的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python字典的用法_Python字典
- 下一篇: python中var是什么_这些Pyth