python的類變數與例項變數以及 dict

2021-08-13 18:15:30 字數 3455 閱讀 6146

關於python的例項變數與類變數,先來看一段可能顛覆世界觀的例子

1

#!/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__是乙個字典,鍵是屬性名,值為屬性值。

python的例項有自己的__dict__,它對應的類也有自己的__dict__   (但是有些特殊的物件是沒有__dict__屬性的,這裡不做討論)

如果在程式的第15行處加上兩句列印語句,列印類和例項1的__dict__屬性,將會輸出如下:

1

print cls.__dict__

2print ins1.__dict__

###########輸出##########

當列印類的__dict__屬性時,列出了類cls所包含的屬性,包括一些類內建屬性和類變數clsvar以及構造方法__init__

而例項變數則包含在例項物件ins1的__dict__屬性中,乙個物件的屬性查詢順序遵循首先查詢例項物件自己,然後是類,接著是類的父類。

現在可以解釋開頭**中的神秘現象了,再強調一遍,乙個物件的屬性查詢順序遵循首先查詢例項物件自己,然後是類,接著是類的父類。

在第18行  ins1.clsvar = 20這句後面我們列印一下例項和類的__dict__屬性

ins1.clsvar = 20

print 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

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

']

但是在了解了__dict__屬性之後可以這樣寫:

1

class

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...