上一章節(jié)主要闡述了類相關(guān)的概念和創(chuàng)建類的基本語法护锤,我們知道類是由數(shù)據(jù)屬性和函數(shù)屬性結(jié)合的裆操,由類可以產(chǎn)生對象怒详,這個過程也叫做實例化,我們得到的結(jié)果就是實例踪区,所以實例就是對象昆烁,是由類這樣一個模板所產(chǎn)生的,那么既然實例(對象)是由類產(chǎn)生的缎岗,問題來了静尼,請問實例是否能使用類的數(shù)據(jù)屬性和函數(shù)屬性呢,我們帶著這個問題來一步一步學習
-
類的數(shù)據(jù)屬性和函數(shù)屬性在什么地方被存儲传泊?
我們知道如何去定義一個類鼠渺,如下:
class Person:
x = 1 #數(shù)據(jù)屬性
def func(self): #函數(shù)屬性
pass
我們定義了一個Person類,其中包含了數(shù)據(jù)屬性x和函數(shù)屬性func,那么這些屬性被存儲在什么地方眷细,下面介紹一個變量叫屬性字典拦盹,這個字典就將類的數(shù)據(jù)屬性和函數(shù)屬性存儲起來,具體的操作如下:
print(Person.__dict__) #類名.__dict__
通過上述方式就能訪問屬性字典薪鹦,我們會得到如下結(jié)果
{'__module__': '__main__', 'x': 1, 'func': <function Person.func at 0x02D30228>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
我們可以看到無論是函數(shù)屬性還是數(shù)據(jù)屬性掌敬,在字典中的變成了鍵,并且鍵的類型是字符串池磁,如果你只想得到訪問函數(shù)屬性奔害,操作如下
print(Person.__dict__['func'])
值得注意的是我們的鍵必須是字符串
-
實例(對象)如何由類產(chǎn)生?
我們知道實例是由類產(chǎn)生的地熄,產(chǎn)生過程叫做實例化华临,那如何產(chǎn)生,語法如下
class Person:
x = 1 #數(shù)據(jù)屬性
def func(self): #函數(shù)屬性
pass
p = Person() ---> 實例化過程端考,此時p就是Person的一個實例
一個類可以產(chǎn)生多個實例雅潭,比如
class Person:
x = 1 #數(shù)據(jù)屬性
def func(self): #函數(shù)屬性
pass
p1 = Person()
p2 = Person()
p3 = Person()
每一個實例都是獨立,前面我們說到類屬性字典却特,而實例是類產(chǎn)生而來扶供,那么實例也應該有屬性字典,沒錯實例也有自己的屬性字典裂明,我們可以訪問實例的屬性字典椿浓,看一看實例的屬性字典中存儲的是什么值
class Person:
x = 1 #數(shù)據(jù)屬性
def func(self): #函數(shù)屬性
pass
p = Person()
print(p.__dict__)
打印結(jié)果
{}
打印結(jié)果為空表明,確實存在實例屬性字典闽晦,但是x,func并不屬于實例的屬性扳碍,x,func是類屬性,它們是歸類所有的仙蛉,所以實例是否可以使用這個屬性呢笋敞,答案是肯定的
class Person:
x = 1 #數(shù)據(jù)屬性
def func(self): #函數(shù)屬性
pass
p = Person()
print(p.x)
打印結(jié)果
1
print(p.x)是為了去找實例p中x屬性,雖然在實例的屬性字典中無法找到荠瘪,但是在類屬性字典能夠找到夯巷,那么就打印,就好比函數(shù)的作用域哀墓,內(nèi)層找不到就去外層找鞭莽。所以當實例去調(diào)用某個屬性的時候,如果在自己的屬性字典中找不到就會去類屬性字典中找麸祷。
-
實例和類之間的關(guān)系
比如我們創(chuàng)建一個中國人的類澎怒,首先中國人所共有的屬性是國籍中國,所以就把共有的屬性放在類屬性中阶牍。實例是由類產(chǎn)生的喷面,上圖中由一個類產(chǎn)生了3個實例,那么每個實例都是一個人走孽,所以每個人都有姓名和年齡對吧惧辈,而姓名、年齡就應該是實例屬性磕瓷,存在于每個實例自己的屬性字典中盒齿,這樣實例與實例之間才是互補干擾的念逞,另外,函數(shù)speak也是中國人所有共有的動作边翁,那么也是放在類的屬性字典中翎承,但是每個實例可以取調(diào)用這個函數(shù),那么問題來了我們怎么給實例加上實例自己的屬性呢符匾,下面就介紹如何給實例添加屬性
-
給實例添加屬性(init方法)
實例屬性和類屬性是獨立叨咖,但是在訪問實例屬性時,如果找不到啊胶,那么就會去類里面找甸各,現(xiàn)在init方法就是給初始化實例屬性的,比如我們有一個需求
1.定義一個類Person焰坪,類屬性country = “China”
2.生成1個實例趣倾,實例要有姓名和年齡
首先定義一個Person類十分簡單
class Person:
country = "China"
按照要求我們要給生成一個實例,并且加上年齡和姓名屬性
p1=Person()
p1.name="ww"
p1.age=12
此時我們?nèi)ゴ蛴嵗龑傩宰值淇煽吹浇Y(jié)果
print(p1.__dict__)
結(jié)果
{"name":"ww","age":12}
說明我們已經(jīng)將屬性添加到了實例p1上某饰,那么問題來了-->我現(xiàn)在要產(chǎn)生第二個實例誊酌,怎么操作,如下:
p2=Person()
p2.name="ww"
p2.age=12
print(p2.__dict__)
當然打印的結(jié)果是一樣的露乏,但是發(fā)現(xiàn)我們在重復的做一件事情就是給實例添加屬性碧浊,此時如果我們在定義類的時候,實現(xiàn)一個init方法瘟仿,那么就可以簡化操作箱锐,具體實現(xiàn)代碼如下:
class Person:
country = "China"
def __init__(self,name,age):
self.name=name
self.age=age
init方法接收的第一個參數(shù)是self,其實在這里我們已經(jīng)能夠看書self是什么了,就是實例劳较,此時我們在進行是實例化的時候驹止,我們就直接把name 和age傳給類
p1 = Person("ww",12) --->自動執(zhí)行__init__方法,將"ww"傳給name,將12傳給age
此時我們就可以通過init方法來初始化我們的實例屬性观蜗,同時我們也可以看到此時實例屬性也被添加到自己的屬性字典中臊恋。