<a href="http://www.cnblogs.com/alex3714/articles/5188179.html" target="_blank">http://www.cnblogs.com/alex3714/articles/5188179.html</a>
<a href="http://www.cnblogs.com/wupeiqi/p/4493506.html" target="_blank">http://www.cnblogs.com/wupeiqi/p/4493506.html</a>
廣度優先: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")
一,封裝:将内容放在某個地方,以後如果有需要,可以用某種函數調用此内容
第一步:将内容封裝到某處:
第二步:從某處調用被封裝的内容
第一步詳解:
def __init__(self,name,age):
self.name=name
self.age=age
#根據類對象Foo建立對象
#自動執行Foo類的__init__方法
obj1=Foo('狂',18)#将狂和18分别封裝到name和age屬性中
第二步詳解:
從某處調用相關函數:
有兩種方案(所有語言中的特性)
1,通過對象直接調用
2,通過self間接調用
我們先來看第一種
obj1=Foo('wupeiqi',18)
print(obj1.name)
print(obj1.age)
obj2=Foo('alex',73)
print(obj2.name)
print(obj2.age)
第二種介紹:
def detail(self):
print(self.name)
print(self.age)
obj1.detail()
obj2.detail()
由此可見,第二種通過self的間接調用指的是通過函數去通路
練習一:在終端輸出如下資訊
小明,10歲,男,上山去砍柴
小明,10歲,男,開車去東北
小明,10歲,男,最愛大保健
老李,90歲,男,上山去砍柴
老李,90歲,男,開車去東北
老李,90歲,男,最愛大保健
def __init__(self,name,age,sex):
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()
<code><br data</code><code>-</code><code>filtered</code><code>=</code><code>"filtered"</code><code>></code>
二,繼承:
繼承,面向對象中的繼承和現實生活中的繼承相同,即:子可以繼承父的内容
比如說 人 ,學生,工作者
學生和工作者就是人的兩個擴充子類
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)
class Cat(Animal):
def __init__(self,name):
self.bread='貓'
def cry(self):
print('喵喵叫')
class Dog(Animal):
def __init__(self, name):
self.name = name
self.bread = '狗'
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是經典類
class C1: #C1是新式類
class C2(C1)#C1是新式類
class D:
def bar(self):
print('D bar')
class C(D):
print('C.bar')
class B(D):
print('B.bar')
class A(B,C):
print('A.bar')
a=A()
a.bar()
深度優先和廣度優先會在爬蟲等多個領域進行運用
第一詳解:
深度優先算法:
(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 href="https://s3.51cto.com/oss/201711/08/117ff53d4779f3aeb01aeecfaeb73ca8.png-wh_500x0-wm_3-wmp_4-s_1760643635.png" target="_blank"></a>
<a href="https://s1.51cto.com/oss/201711/08/a1f0533024bf9b6546cfba343b426558.png-wh_500x0-wm_3-wmp_4-s_3626293800.png" target="_blank"></a>
A-B-D-E-I-C-F-G-H (遞歸實作)
A-B-C-D-E-F-G-H-I (隊列實作)
本文轉自眉間雪 51CTO部落格,原文連結:http://blog.51cto.com/13348847/1980015,如需轉載請自行聯系原作者