一.面向對象程式設計 OOP (Object Oriented Programming)
1.OOP是一種計算機程式設計架構,計算機程式是由單個能夠起到子程式作用的單元或對象組合而成,即把對象作為程式的基本單元。
2.面向對象本身是對面向過程的封裝。
3.OOP的三大特點:封裝、繼承和多态。
4.python是一門徹底的面向對象程式設計(opp)的語言,python中萬物皆對象。
5.python中,所有資料類型都可以視為對象,當然也可以自定義對象。自定義的對象資料類型就是面向對象中的類(Class)的概念。
6.python中,一個對象包括:屬性和方法(變量+函數)
二.類(Class)和執行個體(Instance)
1.對象:類和執行個體
(1)類:用來描述具有相同的屬性和方法的對象的集合,類本質上也是對象
(2)執行個體:具有屬性和方法的對象,執行個體本質上也是對象,在python中執行個體也被稱為對象,為了差別于整個的對象概念,把它稱作執行個體
(3)執行個體抽象出類,類執行個體化為執行個體,一個類可以有多個執行個體
(4)類和執行個體相當于抽象和具體的關系:比如:類:學生;執行個體:張三
2.python中預設繼承(object)的類,也被稱作新式類
3.python中通過一個類對象來建立另一個類對象或對應的執行個體對象,
4.建立類對象的類被稱作元類,type是終極元類
5.類和對象:(1)類=對象=類對象;類屬性(2) 對象=對象=一般對象=執行個體;對象屬性=執行個體屬性
三.建立類和執行個體
1.通過class 建立一個類
2.類的建立流程:檢測__metaclass__屬性:該類--父類--子產品中--type元類
3.根據類名執行個體化一個執行個體
4.類名(money)是變量(money),變量(類名)引用該類,類執行個體化對象,由變量(one)引用該對象,由該對象裡面的__class__找到該類
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classMoney:2 pass
3 one=Money()4 print(type(Money))5 print(type(one))6 print(Money.__name__)#通路類的名稱
7 print(one.__class__)#通路執行個體對應的類
8 ----------------------------------------------------------------------
9
10
11 Money12
建立類和執行個體
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 #type(cls, what, bases=None, dict=None):
2 #建立類:類名=type(類,父類(),{__dict__})
3 #通過元類建立
4 a=10
5 print(type(a))6 xxx=type('dog',(),{'count':0})7 print(xxx)8 print(xxx.__dict__)9 d=xxx()10 print(d)11 -------------------------------------------
12
13
14 {'count': 0, '__module__': '__main__', '__dict__': , '__weakref__': , '__doc__': None}15 <__main__.dog object at 0x0307C4B0>
類對象的建立方式2
四.屬性
1.類屬性和執行個體屬性
(1)類屬性:定義在類中且在函數體之外,可以通過類名通路其屬性;類屬性被對應的各個執行個體中共享;類屬性通常不作為執行個體屬性使用
(2)執行個體屬性:定義在方法中的屬性,隻作用于目前執行個體的類
(3)類對象的__dict__屬性(隻讀屬性)預設不能被指派修改,可以通過setattr方法修改;而一般對象裡面的__dict__屬性能被直接修改
(4)一般情況下,屬性存儲在__dict__的字典中,有些内置對象沒有這個__dict__屬性
(5)能通過執行個體找到類屬性,不能通過類通路執行個體屬性
(6)變量後面加_:表示與系統關鍵字進行區分的命名方式;變量後面加__:表示系統内置的寫法
(7)執行個體屬性通路機制:getattribute方法---調用描述器方法的get方法---執行個體自身的dict字典---對應類的dict字典---父類(上層)的dict字典---調用getattr方法
2.類屬性的增、删、改、查
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classmoney:2 age=19
3 num=123 #直接在類中添加屬性
4 money.count=1#給類增加一些屬性,類屬性=值
5 money.age=3#給類的屬性直接指派;來改變屬性值
6 print(money.count)7 print(money.age)8 print(money.__dict__)#檢視類的所有屬性,以字典形式傳回(類的内置屬性和建立的屬性)
9
10 m=money11 print(m.age)#通過對象通路類的屬性
12 print(m.__name__)13 print(m.__class__)14
15 #del 删除類的直系屬性
16 #不能通過對象删除累屬性
17 -----------------------------------------------------
18 1
19 3
20 {'__module__': '__main__', 'age': 3, 'num': 123, '__dict__': , '__weakref__': , '__doc__': None, 'count': 1}21 3
22 money23
24
25 類屬性
類屬性的增、删、改、查
3.執行個體屬性的增、删、改、查
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classPerson:2 pass
3 p=Person()4
5 #給p對象增加一些屬性,對象屬性=值
6 p.age=18
7 #驗證是否有添加成功
8 print(p.age)9 print(p.__dict__)#檢視對象的所有屬性,以字典形式傳回
10
11 p.age=[1,3]#修改操作,直接指派修改對象的屬性,id會變
12 print(p.age)13
14 p.age.append('小花')#通路操作,操作(添加)值,id不變
15 print(p.age)16
17 #del 删除
18 ---------------------------------------------------------
19 18
20 {'age': 18}21 [1, 3]22 [1, 3, '小花']
執行個體屬性的增、删、改、查
4.限制執行個體屬性的添加__slots__
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classperson:2 __slots__ = ['age']#限制對象屬性的添加
3 pass
4 p1=person()5 p1.age=10
6 #p1.num=10 報錯AttributeError: 'person' object has no attribute 'num'
7 print(p1.age)8 ----------------------------------------------
9 10
限制對象屬性的添加__slots__
5.python中對象的屬性查找機制:優先到對象自身去查找屬性,找到則結束;如果沒找到,則根據__class__找到對象對應的類,到類裡面查找
6.公有屬性、受保護屬性、私有屬性
(1)公有屬性:共享的屬性,一般的屬性
(2)受保護屬性:受到保護的屬性,用 _ 字首表示
(3)私有屬性:防止外界直接通路,防止被子類同名稱屬性覆寫,進行資料保護和資料過濾,用 __ 字首表示,執行個體不能通路私有屬性
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classperson:2 def __init__(self):3 self.__age=18
4
5 defsetAge(self,value):6 if isinstance(value,int) and 0
7 self.__age=value8 else:9 print('資料錯誤')10
11 defgetAge(self):12 return self.__age
13
14 p=person()15 print(p._person__age)16 p.setAge(20)17 print(p._person__age)18 print(p.getAge())19 -------------------------------------------------
20 18
21 20
22 20
私有化屬性
私有屬性的通路(名字重整):__類名 變為 _類名__x
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classAnimal:2 __x = 10
3 deftest(self):4 print(Animal.__x)5 print(self.__x)6
7 print(Animal.__dict__)8 print(Animal._Animal__x)9 -------------------------------------------------
10 {'__module__': '__main__', '_Animal__x': 10, 'test': , '__dict__': , '__weakref__': , '__doc__': None}11 10
私有屬性名稱重整
7.隻讀屬性(隻能讀取,不能寫入):(1)先私有化,再部分公開,;利用@property裝飾器(2)__setattr__
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classPerson:2 def __init__(self):3 self.__age=18
4
5 defgetAge(self):6 return self.__age
7
8 @property #可以将一些屬性的操作方法關聯這個方法
9 #property(fget=Nofne, set=None, fdel=None, doc=None)
10 defage(self):11 return self.__age
12 p=Person()13 print(p.getAge())14 print(p.age)15 #p.age=666 #AttributeError: can't set attribute
16 -------------------------------------------------------------
17 18
18 18
隻讀屬性1
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classPerson:2 def __setattr__(self, key, value):3 print(key, value)4 if key=='age'and key in self.__dict__.keys():5 print('隻讀屬性')6 else:7 self.__dict__[key]=value8
9 p=Person()10 p.age=19
11 p.name='sz'
12 print(p.__dict__)13 print(p.age)14 p.age=12
15 print(p.age)16 -------------------------------------------
17 age 19
18 name sz19 {'age': 19, 'name': 'sz'}20 19
21 age 12
22 隻讀屬性23 19
隻讀屬性2
五.方法
1.在類内部,使用 def 關鍵字來定義一個方法;調用:對象.方法
2.與一般函數定義不同,方法必須包含形式參數 self, 且為第一個參數,self 代表的是對象本身
3.self 代表的是類的執行個體,代表目前對象的位址,而 self.class 則指向類,self 不是 python 關鍵字,可以認為方法中的self其實就是執行個體對象的唯一标志
4.執行個體方法、類方法、靜态方法
(1)無論哪種類型的方法,都是存儲在類中,在類的__dict__指向的字典中,沒有在執行個體當中的方法
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classperson:2 defshilifangfa(self):3 print('執行個體方法',self)4
5 @classmethod6 defleifangfa(cls):7 print('類方法',cls)8
9 @staticmethod10 defjingtaifanggfa():11 print('靜态方法')12
13 p=person()14 p.shilifangfa()15 print(p)16 #person.shilifangfa()#TypeError: shilifangfa() missing 1 required positional argument: 'self'
17
18 person.leifangfa()19 person.jingtaifanggfa()20 -----------------------------------------------------------------
21 執行個體方法 <__main__.person object at 0x052B6070>
22 <__main__.person object at 0x052B6070>
23 類方法
24 靜态方法
定義在類中的方法
(2)執行個體方法:預設第一個參數需要接受到一個執行個體;調用:對象.方法
(3)類方法:預設第一個參數需要接受到一個類,綁定在類上的方法
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classPerson:2 @classmethod#類方法裝飾器
3 def leifangfa(cls,a):#第一個參數預設為類
4 print('類方法',cls,a)5
6 Person.leifangfa(123)#通過類來調用
7 p=Person()8 p.leifangfa(666)#通過執行個體來調用
9
10 func=Person.leifangfa#通過定義函數的形式來調用
11 func(111)12
13 classA(Person):14 pass
15 A.leifangfa(1)#通過衍生類來調用
16 ----------------------------------------------------------
17 類方法 123
18 類方法 666
19 類方法 111
20 類方法 1
21
22 類方法
類方法的調用
(4)靜态方法:第一個參數什麼也不預設接受;
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classPerson:2 @staticmethod#靜态方法裝飾器
3 defjingtai():4 print('靜态方法')5
6 Person.jingtai()#通過類來調用
7 p=Person()8 p.jingtai()#通過執行個體來調用
9 func=Person.jingtai#通過定義函數的形式來調用
10 func()11 ------------------------------------------
12 靜态方法13 靜态方法14 靜态方法
靜态方法
(5)三種方法的通路權限
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classPerson:2 age=5
3 defshilifangfa(self):4 print('執行個體方法',self)5 print(self.age)6 print(self.num)7
8 @classmethod9 defleifangfa(cls):10 print('類方法',cls)11 print(cls.age)12 print(cls.num)13 @staticmethod14 defjingtaifanggfa():15 print('靜态方法')16 print(Person.age)#通路類屬性
17
18 p=Person()19 p.num=10
20 p.shilifangfa()#執行個體方法既能通路執行個體屬性,又能通路類屬性
21
22 #p.leifangfa()#AttributeError: type object 'Person' has no attribute 'num'
23 #Person.leifangfa()#AttributeError: type object 'Person' has no attribute 'num'
24 #類方法不能通路執行個體屬性,但能通路類屬性
25
26 Person.jingtaifanggfa()27 #靜态方法可以通路類屬性,但不能通路執行個體屬性
28 --------------------------------------------------------------------
29 執行個體方法 <__main__.Person object at 0x054B6170>
30 5
31 10
32 靜态方法33 5
三種方法的通路
5.類的私有方法__private_method(相似私有屬性):聲明該方法為私有方法,隻能在類的内部調用 ,不能在類地外部調用,self.__private_methods
6.類的特殊方法
(1)init初始化
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classmyclass:2 """一個簡單是執行個體"""
3 i=21313
4 deff(self):5 return 'hello world'
6
7 #__init__()将對象建立為有初始狀态的
8 #類定義了 __init__() 方法的話,類的執行個體化操作會自動調用 __init__() 方法
9 #__init__() 方法可以有參數,參數通過 __init__() 傳遞到類的執行個體化操作上
10 def __init__(self,realpart):11 self.r =realpart12
13
14 x=myclass(3.4) #執行個體化類
15 print(x.r)16 print(x.f)17 ------------------------------------------------------------------
18 3.4
19 >
init()
(2)資訊格式化操作,用字元串描述執行個體:__str__和__repr__
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classperson:2 def __init__(self,n,a):3 self.name=n4 self.age=a5 def __str__(self):#資訊格式化,用字元串描述執行個體,面向使用者,通過print或str觸發
6 return '姓名:{},年齡:{}'.format(self.name,self.age)7 def __repr__(self):#資訊格式化,用字元串描述執行個體,面向開發人員,通過執行個體本身或repr觸發
8 return 'repr'
9 #先找__str__,如果沒有,再找__repr__
10 p=person('sz',18)11 print(p.name)12 print(p,type(p))#方法裡的傳回值#沒有__str__方法時<__main__.person object at 0x04C86070>
13 print(str(p),type(str(p)))#字元串
14 print(repr(p))#擷取執行個體的本質資訊,可以用eval再次轉換
15 -------------------------------------------
16 sz17 姓名:sz,年齡:18
18 姓名:sz,年齡:18
19 repr
str和repr
(3)調用操作:__call__方法,使對象具備當做函數來調用的能力
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classperson:2 def __init__(self,name):3 self.name=name4 def __call__(self,age):5 print('姓名:{},年齡:{}'.format(self.name,age))6
7
8 p=person('zyl')9 p(28)#使執行個體能被調用,傳入參數
10 p(23)11 p(14)12 ---------------------------------------------
13 姓名:zyl,年齡:28
14 姓名:zyl,年齡:23
15 姓名:zyl,年齡:14
__call__
(4)索引操作:對一個執行個體進行索引,三個内置方法:setitem,getitem,delitem
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classperson:2 def __init__(self):3 self.cache={}#增加一個字典屬性
4 def __setitem__(self, key, value):#設定/增添鍵值
5 print('setitem',key,value)6 self.cache[key]=value7
8 def __getitem__(self, item):#擷取鍵值
9 #print('getitem',item)
10 returnself.cache[item]11
12 def __delitem__(self, key):#删除操作
13 #print('setitem',key)
14 delself.cache[key]15
16
17 p=person()18 p['name']='sz'#setitem
19 print(p['name'])#getitem
20 del p['name']21 print(p.cache)#查詢字典
22 ---------------------------------------------------
23 setitem name sz24 sz25 {}
索引
(5)切片操作:對一個執行個體進行切片操作,三個内置方法:setitem,getitem,delitem
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classperson:2 def __init__(self):3 self.items=[1,2,3,4,5,6,7,8,]#初始化以清單形式
4 def __setitem__(self, key, value):#切片時隻能修改,不能新增
5 print(key,value)6 print(key.start)7 print(key.stop)8 print(key.step)9 self.items[key]=value10 #if isinstance(key,slice):#容錯處理
11 #self.items[key.start:key.stop:key.step]=value
12
13 def __getitem__(self, item):#擷取資訊
14 print('getitem',item)15
16 def __delitem__(self, key):#删除
17 print('setitem',key)18
19
20 p=person()21 print(p)22 print(p.items)23 p[0:4:2]=['a','b']#對進行切片操作,修改清單
24 print(p.items)25 -------------------------------------------------------------------
26 <__main__.person object at 0x0352C4B0>
27 [1, 2, 3, 4, 5, 6, 7, 8]28 slice(0, 4, 2) ['a', 'b']29 030 4
31 2
32 ['a', 2, 'b', 4, 5, 6, 7, 8]
切片
(6)比較操作:比較大小,真假
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classperson:2 def __init__(self,age,height):3 self.age=age4 self.height=height5 def __eq__(self, other):#實作相等操作
6 print(other)7 return self.age==other.age#傳回操作後的值
8 def __ne__(self, other):#不相等
9 print('xxx')10 def __gt__(self, other):#大于
11 pass
12 def __ge__(self, other):#大于等于
13 pass
14 def __lt__(self, other):#小于
15 print('lt')16 def __le__(self, other):#小于等于
17 pass
18 def __bool__(self):#布爾類型,傳回執行個體是True還是False
19 return self.age>18#傳回值控制執行個體是True還是False
20
21
22 p1=person(18,180)23 p2=person(17,190)24 print(p1==p2)25 print(p1!=p2)26 print(p1
28 <__main__.person object at 0x059A60D0>
29 False30 xxx31 None32 lt33 None
比較
(7)周遊操作:getitem、iter、next,類中同時有iter和next方法的執行個體才是一個疊代器,利用iter擷取疊代器對象,利用next通路疊代器
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classperson:2 def __init__(self):3 self.result=1
4 def __getitem__(self, item):5 self.result+=1
6 if self.result>=6:7 raise StopIteration('停止周遊')8 returnself.result9
10 p=person()11 for i inp:12 print(i)13 --------------------------------------------
14 2
15 3
16 4
17 5
getitem
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classperson:2 def __init__(self):3 self.result=1
4 #iter優先級高于getitem
5 def __iter__(self):#擷取執行個體的疊代器
6 print('iter')7 return self#傳回是一個疊代器對象
8 def __next__(self):#對于疊代器調用next方法
9 self.result+=1
10 if self.result>=6:11 raise StopIteration('停止周遊')12 return self.result#對于疊代器進行周遊
13 p=person()14 for i inp:15 print(i)16 --------------------------------------------
17 iter18 2
19 3
20 4
21 5
iter
(8)描述器:可以描述一個屬性操作的對象;property用來管理屬性通路。資料描述器(get/set)>執行個體屬性>非資料描述器(get)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classPerson(object):2 def __init__(self):3 self.__age=18
4 defget_age(self):5 return self.__age
6 defset_age(self,value):7 self.__age=value8 #property(fget=None, fset=None, fdel=None, doc=None)
9 age=property(get_age,set_age)10 p=Person()11 print(p.age)12 p.age=98
13 print(p.age)14 print(p.__dict__)15
16
17
18 classPerson2(object):19 def __init__(self):20 self.__age=18
21 @property22 defage(self):23 return self.__age
24 @age.setter25 defage(self,value):26 self.__age=value27 p2=Person2()28 print(p2.age)29 p2.age=98
30 print(p2.age)31 print(p2.__dict__)32 ----------------------------------------------------------------------
33 18
34 98
35 {'_Person__age': 98}36 18
37 98
38 {'_Person2__age': 98}
property
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classAge:2 def __get__(self, instance, owner):3 print('get')4 def __set__(self, instance, value):5 print('set')6 def __delete__(self, instance):7 print('delete')8 classperson:9 age=Age()#描述器
10 def __getattribute__(self, item):11 print('xxx')12
13 #通過執行個體操作描述器
14 p=person()15 p.age=10#調用了set,get
16 print(p.age)#調用的方法中沒有傳回值
17 del p.age#調用了delete
18 #一般不通過類來操作描述器
19 print(person.age)#隻是調用了get方法
20 person.age=19
21 del person.age#沒有用delete方法
22 ---------------------------------------------------------------------
23 set24 xxx25 None26 delete27 get28 None
描述器
7.補充
(1)__new__方法:建立執行個體對象,将對象建立出來,傳回執行個體對象,主要用于繼承一些不可變的類,一般預設
(2)__init__方法:初始化執行個體對象,一般用于定義初始化屬性,當對象被建立,自動執行,無需傳回值,若還有new方法,則執行new
(3)__call__方法:使得類能像函數那樣調用,一般放類的執行
六.繼承
classDerivedClassName(BaseClassName):
或
classDerivedClassName(modname.BaseClassName):
其中DerivedClassName子類 BaseClassName基類
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 class people: #類定義
2 name = '' #定義基本屬性
3 age = 0 #定義基本屬性
4 __weight = 0 #定義私有屬性,私有屬性在類外部無法直接進行通路
5
6 def __init__(self, n, a, w):#定義構造方法
7 self.name =n8 self.age =a9 self.__weight =w10
11 def speak(self): #定義構造方法
12 print("%s 說: 我 %d 歲。" %(self.name, self.age))13
14 class student(people): #單繼承示例,定義基類
15 grade = ''
16
17 def __init__(self, n, a, w, g):18 people.__init__(self, n, a, w)#調用父類的構函
19 self.grade =g20
21 def speak(self): #覆寫父類的方法
22 print("%s 說: 我 %d 歲了,我在讀 %d 年級" %(self.name, self.age, self.grade))23
24 class speaker(): #另一個類,多重繼承之前的準備
25 topic = ''
26 name = ''
27
28 def __init__(self, n, t):29 self.name =n30 self.topic =t31
32 defspeak(self):33 print("我叫 %s,我是一個演說家,我演講的主題是 %s" %(self.name, self.topic))34
35 #多重繼承
36 classsample(speaker, student):37 a = ''
38
39 def __init__(self, n, a, w, g, t):40 student.__init__(self, n, a, w, g)41 speaker.__init__(self, n, t)42
43
44 test = sample("Tim", 25, 80, 4, "Python")45 test.speak() #方法名同,預設調用的是在括号中排前地父類的方法
46 ------------------------------------------------------------------------------
47 我叫 Tim,我是一個演說家,我演講的主題是 Python
繼承
1.子類(派生類)繼承父類(超類)(基類):子類擁有父類一些資源的'使用權'
2.父類---共性;子類---特性
3.單繼承:僅僅繼承一個父類;多繼承:繼承多個父類;多繼承分為無重疊的多繼承,有重疊的多繼承
4.可以在子類中重寫父類的方法
5.supper()調用父的一個方法,自動找到所有基類以及對應的方法
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classDongwu():2 def __init__(self,name):3 self.name=name4 defshengming(self):5 print('dongwu')6
7 classGou(Dongwu):8 def __init__(self,name,color):9 super().__init__(name) #調用父類的一個方法,從父類獲得繼承
10 self.color=color #在子類中添加新的内容
11 defshengming(self):12 print('gou')13 defkanjia(self):14 print('kanjia')15
16 a1=Dongwu('a1')17 a2=Gou('a2',1)18 print(a1.shengming(),a2.shengming())19 ----------------------------------------------------------------------------
20 dongwu21 gou
super
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classD:2 def __init__(self):3 print('d')4 classB(D):5 def __init__(self):6 D.__init__(self)#調用父類的方法
7 print('b')8 classC(D):9 def __init__(self):10 super().__init__()11 print('c')12 classA(C,B):13 def __init__(self):14 #B.__init__(self)
15 #C.__init__(self)調用了兩次
16 #super沿着mro鍊條,找到下一級節點,去調用對應的方法
17 #super(__class__, )沿着參數二的mro鍊條,找參數一的下一個節點
18 #使用參數二進行調用
19 super(A, self).__init__()20 #super().__init__()
21 print('a')22 C()23 A()24 -------------------------------------
25 d26 c27 d28 b29 c30 a
super
6.type和object
(1)type:元類,執行個體化其他類,包括object類,type類執行個體化object類
(2)object:所有類的父類,包括type類,type類繼承object類
7.資源:除了私有的方法和屬性,其他的基本都能繼承;資源的‘使用權’實質上指資源的通路權,并不是指資源的複制
8.資源的使用:
(1)單繼承鍊:從下到上
(2)無重疊的多繼承鍊:從左到右,從上到下
(3)有重疊的多繼承鍊:從上到下,從左到右,(新式類,c3算法)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 #檢視資源查找順序
2 importinspect3 classanimal:4 pass
5 classperson(animal):6 pass
7 inspect.getmro(person)#檢視類資源的通路循序
8 print(person.__mro__)9 print(person.mro())10 ---------------------------------------------------------------
11 (, , )12 [, , ]
資源查找
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classD:2 pass
3 classB(D):4 pass
5 classC(D):6 pass
7 classA(C,B):8 pass
9 print(A.mro())10 -----------------------------------------------
11 [, , , , ]
資源查找
9.資源的覆寫:屬性的覆寫和方法的重寫;本質是通路優先級順序決定的
七.記憶體管理機制
1.所有對象都會在記憶體中開辟一塊空間進行存儲;根據不同的類型及内容開辟不同的空間大小進行存儲,并傳回該空間的位址給外界接受(引用),用于後續對這個對象的操作
2.對于整數和短小的字元,python會進行緩存,不會建立多個相同對象
3.容器對象(清單,元組,字典,自定義類對象等),存儲的其他對象,僅僅是其他對象的引用,并不是其他對象本身
4.引用計數器:對象自身被引用的個數
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 importsys2 classperson:3 pass
4 p1 = person() #p1引用person類對象====把person類對象的位址指派給p1
5 print(sys.getrefcount(p1))#檢視p1引用的對象的引用個數,注意初始為一即結果是:實際引用個數加一
6 p2 = p1#把p1的值指派給p2,p1的值是person類對象的位址,p2引用person類對象,p2的值是person類對象的位址
7 print(sys.getrefcount(p1)) #檢視對象(person類對象)引用個數,注意初始為一即結果是:實際引用個數加一
8 delp29 print(sys.getrefcount(p1)) #檢視p1引用的對象的引用個數
10
11 #引用計數加一:
12 #p1=person()對象被建立
13 p2=p1#對象被引用,3
14 print(sys.getrefcount(p1))15 l=[p1]#對象作為一個元素存儲在容器中,引用次數加一,4
16 print(sys.getrefcount(p1))17
18 #引用次數+2
19 deflog(obj):20 print(sys.getrefcount(obj))21 log(p1)#對象被作為參數,傳入到一個函數中,6
22
23 #引用次數減一:
24 #del p1對象的别名被顯示銷毀
25 #p1 = 123 對象的别名被賦予新的對象
26 #一個對象離開它的作用域:一個函數執行完畢時;内部的局部變量關聯的對象,它的引用會被釋放
27 #對象所在的容器被銷毀,或從容器中删除對象
28 ---------------------------------------------------------------------
29 2
30 3
31 2
32 3
33 4
34 6
引用計數器
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 #循環引用
2 importobjgraph3 classperson:4 pass
5 classdog:6 pass
7
8 p=person()9 d=dog()10 print(objgraph.count('person'))#垃圾回收器,檢視跟蹤的對象個數
11 print(objgraph.count('dog'))12 p.pet=d13 d.master=p14 print(objgraph.count('person'))15 print(objgraph.count('dog'))16
17 delp18 deld19 print(objgraph.count('person'))#對象并沒有被釋放
20 print(objgraph.count('dog'))21 -----------------------------------------------------------------
22 1
23 1
24 1
25 1
26 1
27 1
循環引用
5.垃圾回收機制:解決循環引用問題:找到循環引用并幹掉相關對象
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 #垃圾回收機制
2 #找到循環引用
3 #1.收集所有容器對象,通過一個雙向連結清單進行引用
4 #2.對于每一個‘容器對象’,通過gc_refs來記錄目前對應的引用計數
5 #3.對于每一個‘容器對象’,找到它引用的‘容器對象’,并将這個‘容器對象’的引用計數-1
6 #4.通過引用計數判斷是否是循環引用,計數器為0的為循環引用,可以被釋放
7
8
9 #垃圾回收器中,新增的對象個數-消亡的個數達到一定門檻值是才會觸發垃圾檢測
10 #垃圾回收的周期順序:0代垃圾回收一定次數才會觸發0,1代回收;1代垃圾回收一定次數才會觸發0,1,2代回收
11 importgc12 importobjgraph13 print(gc.get_threshold())#得到垃圾檢測的參數(門檻值,10代,10代)
14 gc.set_threshold(800,10,10)#設定垃圾檢測的參數
15 print(gc.get_threshold())16
17 #垃圾回收:
18 #自動回收:開啟垃圾回收機制;達到垃圾回收的門檻值
19 print(gc.isenabled())#檢測垃圾回收機制是否開啟
20 gc.disable()#關閉垃圾回收機制
21 print(gc.isenabled())22 gc.enable()#開啟垃圾回收機制
23 print(gc.isenabled())24
25 #手動回收:
26 classperson:27 def __del__(self):28 print('person對象被釋放了')29 classdog:30 def __del__(self):31 print('dog對象被釋放了')32 p=person()33 d=dog()34 #兩個執行個體對象之間互相引用,造成循環引用
35 p.pet=d36 d.master=p#python2中弱引用weakref.ref()
37 delp38 deld39 gc.collect()#手動回收垃圾,無關垃圾自動清理機制是否開啟
40 print(objgraph.count('person'))41 print(objgraph.count('dog'))42 --------------------------------------------------------------------
43 (700, 10, 10)44 (800, 10, 10)45 True46 False47 True48 person對象被釋放了49 dog對象被釋放了50 051 0
垃圾回收機制
八.補充
1.如果對象的屬性和方法名相同,屬性會覆寫方法
1.封裝:把操作和屬性封裝在一個對象中
2.多态:對象行為和屬性的多态;python中并沒有真正的多态,也不需要多态
3.一個疊代器一定是一個可疊代對象,一個可疊代對象不一定是疊代器;可疊代對象:iter;疊代器:iter和next
4.重載
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 classDw():2 def __init__(self,name):3 self.name=name4 #<__main__.Dw object at 0x02BD73D0>
5
6 def __str__(self):7 returnself.name8 #a
9
10 def __repr__(self):11 return 'name:' +self.name12 #name:a
13
14 a=Dw('a')15 print(a)16 ------------------------------------------------
17 a
重載
5.組合:直接在類定義中把需要的類放進去執行個體化
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 #組合:把類和執行個體化方方放到新類中,把幾個沒有關系的類放到一起
2 classTurtle:3 def __init__(self,x):4 self.num=x5 classFish:6 def __init__(self,x):7 self.num =x8 classPool:9 def __init__(self,x,y):10 self.turtle=Turtle(x)11 self.fish=Fish(y)12 defprint_num(self):13 print(self.turtle.num,self.fish.num)14
15 pool=Pool(1,10)16 pool.print_num()17 ----------------------------------------------------------------------
18 1 10
組合
6.生成項目文檔pydoc:(1):cmd--轉到檢視python檔案的目錄;檢視文檔描述: python -m pydoc 子產品名稱
(2)啟動本地服務,浏覽web文檔:python -m pydoc -p 端口号
(3)生成指定子產品html文檔 : python -m pydoc -w 子產品名稱
(4)-k 檢視相關的子產品
(5)-h幫助文檔python -m pydoc -h 子產品
(6)-b自己開啟端口python -m pydoc -b
7.抽象類和抽象方法:抽象類:抽象出來的類,不能直接建立執行個體的類,建立會報錯;抽象方法:抽象出來的方法,不具備具體實作,不能直接調用,子類不實作會報錯
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLrN2bsJEZlR3YhJHdu92Qvw1cy9GdhNWak5WSn5WaulGb0V3TvwVbvNmLzd2bsJmbj5ycldWYtl2Lc9CX6MHc0RHaiojIsJye.gif)
1 importabc2 class animal(object,metaclass=abc.ABCMeta):3 @abc.abstractmethod4 defjiao(self):5 pass
6 classdog(animal):7 defjiao(self):8 print('wang')9
10 classcat(animal):11 defjiao(self):12 print('miao')13
14 deftest(obj):15 obj.jiao()16
17 d=dog()18 d.jiao()19 --------------------------------------
20 wang
抽象