python面向对象基础
感謝前輩們的指導,http://www.cnblogs.com/yupeng/p/3414736.html
http://www.cnblogs.com/alex3714/articles/5188179.html
http://www.cnblogs.com/wupeiqi/p/4493506.html
深度優先:https://www.cnblogs.com/yupeng/p/3414736.html
廣度優先:https://www.cnblogs.com/zhaof/p/7092400.html
個人將五篇博客里面的優點總結到一起,并懷著對前輩們的尊敬,以下均是純手打,代碼已經過驗證
可以在python3.6.3中運行
面向對象是一種編程方式,需要類和對象來實現,面向對象編程其實就是對類和對象的使用
類就是指一個模板,模板里的的函數可以有多個,函數里實現一些功能
對象根據模板創建實例,通過實例對象執行類中的函數
面向對象;【創建對象】【通過對象執行方法】
class Foo:
? ? def Bar(self):
? ? ? ? print("Bar")
? ? def Hello(self,name):
? ? ? ? print("i am %s"%(name))
obj=Foo()
obj.Bar()
obj.Hello("wupeiqi")
面向對象三大特點:封裝,繼承,多態一,封裝:將內容放在某個地方,以后如果有需要,可以用某種函數調用此內容
第一步:將內容封裝到某處:
第二步:從某處調用被封裝的內容
第一步詳解:
class Foo:
? ? def __init__(self,name,age):
? ? ? ? self.name=name
? ? ? ? self.age=age
#根據類對象Foo創建對象
#自動執行Foo類的__init__方法
obj1=Foo('狂',18)#將狂和18分別封裝到name和age屬性中
第二步詳解:
從某處調用相關函數:
有兩種方案(所有語言中的特性)
1,通過對象直接調用
2,通過self間接調用
我們先來看第一種
class Foo:
? ? def __init__(self,name,age):
? ? ? ? self.name=name
? ? ? ? self.age=age
obj1=Foo('wupeiqi',18)
print(obj1.name)
print(obj1.age)
obj2=Foo('alex',73)
print(obj2.name)
print(obj2.age)
第二種介紹:
class Foo:
? ? def __init__(self,name,age):
? ? ? ? self.name=name
? ? ? ? self.age=age
? ? def detail(self):
? ? ? ? print(self.name)
? ? ? ? print(self.age)
obj1=Foo('wupeiqi',18)
obj1.detail()
obj2=Foo('alex',73)
obj2.detail()
由此可見,第二種通過self的間接調用指的是通過函數去訪問
練習一:在終端輸出如下信息
-
小明,10歲,男,上山去砍柴
-
小明,10歲,男,開車去東北
-
小明,10歲,男,最愛大保健
-
-
老李,90歲,男,上山去砍柴
-
老李,90歲,男,開車去東北
-
老李,90歲,男,最愛大保健
-
class Foo:
-
? ? def __init__(self,name,age,sex):
-
? ? ? ? self.name=name
-
? ? ? ? self.age=age
-
? ? ? ? self.sex=sex
-
-
? ? def kanchai(self):
-
? ? ? ? print("%s,%s歲,%s,上山去砍柴" % (self.name, self.age, self.sex))
-
-
? ? def qudongbei(self):
-
? ? ? ? print("%s,%s歲,%s,開車去東北" % (self.name, self.age, self.sex))
-
-
? ? def dabaojian(self):
-
? ? ? ? print("%s,%s歲,%s,最愛大保健" % (self.name, self.age, self.sex))
-
-
xiaoming = Foo('小明',10, '男')
-
xiaoming.kanchai()
-
xiaoming.qudongbei()
-
xiaoming.dabaojian()
-
-
laoli = Foo('老李',90, '男')
-
laoli.kanchai()
-
laoli.qudongbei()
-
laoli.dabaojian()
| 1 | <br data-filtered="filtered"> |
二,繼承:
繼承,面向對象中的繼承和現實生活中的繼承相同,即:子可以繼承父的內容
比如說 人 ,學生,工作者
學生和工作者就是人的兩個擴展子類
class Animal:
? ? def eat(self):
? ? ? ? print('%s 吃'%self.name)
? ? def drink(self):
? ? ? ? print('%s 喝'%self.name)
? ? def shit(self):
? ? ? ? print('%s 拉'%self.name)
? ? def pee(self):
? ? ? ? print('%s 撒'%self.name)
? ? def pee(self):
? ? ? ? print('%s 撒'%self.name)
class Cat(Animal):
? ? def __init__(self,name):
? ? ? ? self.name=name
? ? ? ? self.bread='貓'
? ? def cry(self):
? ? ? ? print('喵喵叫')
class Dog(Animal):
? ? def __init__(self, name):
? ? ? ? self.name = name
? ? ? ? self.bread = '狗'
? ? def cry(self):
? ? ? ? print('汪汪叫')
c1 = Cat('小白家的小黑貓')
c1.eat()
c2 = Cat('小黑的小白貓')
c2.drink()
d1 = Dog('胖子家的小瘦狗')
d1.eat()
所以對于面向對象的繼承來講,其實就是將多個類共有的方法提取到父類中,子類僅需繼承父類而不必實現每一種方法
那么一個很關鍵的問題來了,對于多繼承,我們該怎么辦呢,如何準備呢
是否可以繼承多個類
如果繼承多個類每個類中定義了相同的函數,那么哪一個會被使用呢
1、Python的類可以繼承多個類,Java和C#中則只能繼承一個類
2、Python的類如果繼承了多個類,那么其尋找方法的方式有兩種,分別是:深度優先和廣度優先
對深度優先和廣度優先的詳解請見附錄:
當類是經典類的時候,多繼承情況下,會按照深度優先方式查找
當類是新式類的時候,多繼承情況下,會按照廣度優先方式查找
區分:當前類或者父類繼承了object類,那么該類便是新式類,否則是經典類
class C1: #C1是經典類
? ? pass
class C2(object)#C1是經典類
? ? pass
class C1: #C1是新式類
? ? pass
class C2(C1)#C1是新式類
? ? pass
class D:
? ? def bar(self):
? ? ? ? print('D bar')
class C(D):
? ? def bar(self):
? ? ? ? print('C.bar')
class B(D):
? ? def bar(self):
? ? ? ? print('B.bar')
class A(B,C):
? ? def bar(self):
? ? ? ? print('A.bar')
a=A()
a.bar()
#?執行bar方法時#?首先去A類中查找,如果A類中沒有,則繼續去B類中找,如果B類中么有,則繼續去C類中找,如果C類中么有,則繼續去D類中找,如果還是未找到,則報錯#?所以,查找順序:A?-->?B?-->?C?-->?D#?在上述查找bar方法的過程中,一旦找到,則尋找過程立即中斷,便不會再繼續找了經典類:首先去A類中查找,如果A類中沒有,則繼續去B類中找,如果B類中么有,則繼續去D類中找,如果D類中么有,則繼續去C類中找,如果還是未找到,則報錯 新式類:首先去A類中查找,如果A類中沒有,則繼續去B類中找,如果B類中么有,則繼續去C類中找,如果C類中么有,則繼續去D類中找,如果還是未找到,則報錯 class?Animal(object):def?__init__(self,?name):??#?Constructor?of?the?classself.name?=?namedef?talk(self):??#?Abstract?method,?defined?by?convention?onlyraise?NotImplementedError("Subclass?must?implement?abstract?method")class?Cat(Animal):def?talk(self):print('%s:?喵喵喵!'?%?self.name)class?Dog(Animal):def?talk(self):print('%s:?汪!汪!汪!'?%?self.name)def?func(obj):??#?一個接口,多種形態obj.talk()c1?=?Cat('小晴') d1?=?Dog('李磊')func(c1) func(d1) 正確代碼 Func函數需要接收一個F1類型或者F1子類的類型"""obj.show()s1_obj?=?S1() Func(s1_obj)?#?在Func函數中傳入S1類的對象?s1_obj,執行?S1?的show方法,結果:S1.shows2_obj?=?S2() Func(s2_obj)?#?在Func函數中傳入Ss類的對象?ss_obj,執行?Ss?的show方法,結果:S2.show復制代碼class?F1:passclass?S1(F1):def?show(self):print'S1.show'class?S2(F1):def?show(self):print'S2.show'#?由于在Java或C#中定義函數參數時,必須指定參數的類型 #?為了讓Func函數既可以執行S1對象的show方法,又可以執行S2對象的show方法,所以,定義了一個S1和S2類的父類 #?而實際傳入的參數是:S1對象和S2對象def?Func(F1?obj): """Func函數需要接收一個F1類型或者F1子類的類型"""print(obj.show())s1_obj?=?S1() Func(s1_obj)??#?在Func函數中傳入S1類的對象?s1_obj,執行?S1?的show方法,結果:S1.shows2_obj?=?S2() Func(s2_obj)??#?在Func函數中傳入Ss類的對象?ss_obj,執行?Ss?的show方法,結果:S2.show 錯誤代碼,版本不對深度優先和廣度優先會在爬蟲等多個領域進行運用
第一詳解:
深度優先算法:
(1)訪問初始頂點v并標記頂點v已訪問。
(2)查找頂點v的第一個鄰接頂點w。
(3)若頂點v的鄰接頂點w存在,則繼續執行;否則回溯到v,再找v的另外一個未訪問過的鄰接點。
(4)若頂點w尚未被訪問,則訪問頂點w并標記頂點w為已訪問。
(5)繼續查找頂點w的下一個鄰接頂點wi,如果v取值wi轉到步驟(3)。直到連通圖中所有頂點全部訪問過為止。
廣度優先算法:
(1)頂點v入隊列。
(2)當隊列非空時則繼續執行,否則算法結束。
(3)出隊列取得隊頭頂點v;訪問頂點v并標記頂點v已被訪問。
(4)查找頂點v的第一個鄰接頂點col。
(5)若v的鄰接頂點col未被訪問過的,則col入隊列。
(6)繼續查找頂點v的另一個新的鄰接頂點col,轉到步驟(5)。直到頂點v的所有未被訪問過的鄰接點處理完。轉到步驟(2)。
第二詳解:
深度優先是指網絡爬蟲會從起始頁開始,一個鏈接一個鏈接跟蹤下去,處理完這條線路之后再轉入下一個起始頁,繼續追蹤鏈接,通過下圖進行理解:
注:scrapy默認采用的是深度優先算法
A-B-D-E-I-C-F-G-H (遞歸實現)
廣度優先,有人也叫寬度優先,是指將新下載網頁發現的鏈接直接插入到待抓取URL隊列的末尾,也就是指網絡爬蟲會先抓取起始頁中的所有網頁,然后在選擇其中的一個連接網頁,繼續抓取在此網頁中鏈接的所有網頁,通過下圖進行理解:
A-B-C-D-E-F-G-H-I (隊列實現)
? ? ? 本文轉自眉間雪 51CTO博客,原文鏈接:http://blog.51cto.com/13348847/1980015,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的python面向对象基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FireFox IE Opera Saf
- 下一篇: PHP问题 —— It is not s