關於python的例項變數與類變數,先來看一段可能顛覆世界觀的例子
1看上去怪怪的,為什麼會出現這種結果呢?這就要了解python中的__dict__屬性了,__dict__是乙個字典,鍵是屬性名,值為屬性值。#!/usr/bin/env python2#
-*- coding: utf_8 -*-3#
date: 2023年10月10日4#
author:蔚藍行56
#首先建立乙個類cls,這個類中包含乙個值為1的類變數clsvar,乙個值為2的例項變數insvar,
7class
cls:
8 clsvar = 1
9def
__init__
(self):
10 self.insvar = 2
1112
#建立類的例項ins1和ins2
13 ins1 =cls()
14 ins2 =cls()
1516
#用例項1為類變數重新賦值並列印
17print'#
'*10
18 ins1.clsvar = 20
19print cls.clsvar #
輸出結果為1
20print ins1.clsvar #
輸出結果為20
21print ins2.clsvar #
輸出結果為1
2223
#用類名為類變數重新賦值並列印
24print'#
'*10
25 cls.clsvar = 10
26print cls.clsvar #
輸出結果為10
27print ins1.clsvar #
輸出結果為20
28print ins2.clsvar #
輸出結果為10
2930
#這次直接給例項1沒有在類中定義的變數賦值
31print'#
'*10
32 ins1.x = 11
33print ins1.x #
輸出結果為11
3435
#然後再用類名給類中沒有定義的變數賦值
36print'#
'*10
37 cls.m = 21
38print cls.m #
輸出結果為21
3940
#再建立乙個例項ins3,然後列印一下ins3的變數
41print'#
'*10
42 ins3 =cls()
43print ins3.insvar #
輸出結果為2
44print ins3.clsvar #
輸出結果為10
45print ins3.m #
輸出結果為21
46print ins3.x #
報錯attributeerror: cls instance has no attribute 'x'
python的例項有自己的__dict__,它對應的類也有自己的__dict__ (但是有些特殊的物件是沒有__dict__屬性的,這裡不做討論)
如果在程式的第15行處加上兩句列印語句,列印類和例項1的__dict__屬性,將會輸出如下:
1print cls.__dict__
2print ins1.__dict__
###########輸出##########
當列印類的__dict__屬性時,列出了類cls所包含的屬性,包括一些類內建屬性和類變數clsvar以及構造方法__init__
而例項變數則包含在例項物件ins1的__dict__屬性中,乙個物件的屬性查詢順序遵循首先查詢例項物件自己,然後是類,接著是類的父類。
現在可以解釋開頭**中的神秘現象了,再強調一遍,乙個物件的屬性查詢順序遵循首先查詢例項物件自己,然後是類,接著是類的父類。
在第18行 ins1.clsvar = 20這句後面我們列印一下例項和類的__dict__屬性
ins1.clsvar = 20print ins1.__dict__
print cls.__dict__
###########輸出##########
可以看到,ins1.clsvar = 20這句只是在例項ins1的__dict__屬性中增加了'clsvar': 20這一鍵值對,而類中的clsvar的值並沒有改變,重要的事情說三遍:乙個物件的屬性查詢順序遵循首先查詢例項物件自己,然後是類,接著是類的父類。當ins1在自己的__dict__中查詢到了clsvar,就不會再向上查詢,所以輸出了值20。但是此時,cls類中的clsvar的值仍然為1。
但是當在第25行通過類名改變了類的clsvar之後,類的__dict__中的clsvar就被改變成10了,這時列印ins1的clsvar,由於之前第18行的原因,ins1在自己的__dict__中找到了clsvar,就輸出了它自己的值20,而ins2自己的__dict__中沒有clsvar,就向上查詢類的__dict__,並找到了類的clsvar,值為10
第46行的ins3一直向上查詢x屬性都沒有找到,就會丟擲attributeerror
像32行和37行這樣給類或例項設定屬性,其實就是在他們各自的__dict__中新增了該屬性,相信現在其他的神秘現象大家也可以自己解釋了。
最後附上乙個將字典轉換成物件的小技巧,如果我們有乙個字典如下:
bokeyuan=現在想將其轉換為乙個物件,通常會這樣寫:
1但是在了解了__dict__屬性之後可以這樣寫:class
dict2obj:
2def
__init__
(self,bokeyuan):
3 self.b = bokeyuan['b']
4 self.o = bokeyuan['o']
5 self.k = bokeyuan['k']
6 self.e = bokeyuan['e']
7 self.y = bokeyuan['y']
8 self.u = bokeyuan['u']
9 self.a = bokeyuan['a']
10 self.n = bokeyuan['n
']
1class
dict2obj:
2def
__init__
(self,bokeyuan):
3 self.__dict__.update(bokeyuan)
python 類之類變數與例項變數
前面,我們已經知道了如何定義乙個python的類,那麼類中可以包含什麼內容呢?乙個python類中,包含了變數和方法。我們看如下 其中的age變數和gender變數定義在類中,但在方法外,這樣的變數就是類變數。類變數為所有例項所共享的變數。對上面的程式做了細微的修改 我們例項化乙個物件 person...
類變數與例項變數
定義乙個英雄類,包含玩家數量,生命值,攻擊力和玩家姓名,同時包含乙個方法攻擊方法,呼叫攻擊方法時顯示如圖資訊,建構函式中需要初始化資料,當玩家加入遊戲後需要顯示玩家姓名和數量 class hero count 0 類變數 def init self 例項變數 self.hp 0 self.attac...
類變數與例項變數
初始 如下class dog num legs 4 類變數 def init self,name self.name name 例項變數一 訪問變數 jack dog jack rose dog rose jack.name,rose.name jack rose jack.num legs,ros...