日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python面向对象基础

發(fā)布時間:2025/3/20 python 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python面向对象基础 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

感謝前輩們的指導(dǎo),http://www.cnblogs.com/yupeng/p/3414736.html

http://www.cnblogs.com/alex3714/articles/5188179.html

http://www.cnblogs.com/wupeiqi/p/4493506.html

深度優(yōu)先:https://www.cnblogs.com/yupeng/p/3414736.html

廣度優(yōu)先:https://www.cnblogs.com/zhaof/p/7092400.html

個人將五篇博客里面的優(yōu)點總結(jié)到一起,并懷著對前輩們的尊敬,以下均是純手打,代碼已經(jīng)過驗證

可以在python3.6.3中運行

面向?qū)ο笫且环N編程方式,需要類和對象來實現(xiàn),面向?qū)ο缶幊唐鋵嵕褪菍︻惡蛯ο蟮氖褂?/p>

類就是指一個模板,模板里的的函數(shù)可以有多個,函數(shù)里實現(xiàn)一些功能

對象根據(jù)模板創(chuàng)建實例,通過實例對象執(zhí)行類中的函數(shù)

面向?qū)ο?【創(chuàng)建對象】【通過對象執(zhí)行方法】

class Foo:

? ? def Bar(self):

? ? ? ? print("Bar")

? ? def Hello(self,name):

? ? ? ? print("i am %s"%(name))

obj=Foo()

obj.Bar()

obj.Hello("wupeiqi")

面向?qū)ο笕筇攸c:封裝,繼承,多態(tài)

一,封裝:將內(nèi)容放在某個地方,以后如果有需要,可以用某種函數(shù)調(diào)用此內(nèi)容

第一步:將內(nèi)容封裝到某處:

第二步:從某處調(diào)用被封裝的內(nèi)容

第一步詳解:

class Foo:

? ? def __init__(self,name,age):

? ? ? ? self.name=name

? ? ? ? self.age=age

#根據(jù)類對象Foo創(chuàng)建對象

#自動執(zhí)行Foo類的__init__方法

obj1=Foo('狂',18)#將狂和18分別封裝到name和age屬性中


第二步詳解:

從某處調(diào)用相關(guān)函數(shù):

有兩種方案(所有語言中的特性)

1,通過對象直接調(diào)用

2,通過self間接調(diào)用

我們先來看第一種

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的間接調(diào)用指的是通過函數(shù)去訪問

練習(xí)一:在終端輸出如下信息

  • 小明,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">

二,繼承:

繼承,面向?qū)ο笾械睦^承和現(xiàn)實生活中的繼承相同,即:子可以繼承父的內(nèi)容

比如說 人 ,學(xué)生,工作者

學(xué)生和工作者就是人的兩個擴展子類

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()


所以對于面向?qū)ο蟮睦^承來講,其實就是將多個類共有的方法提取到父類中,子類僅需繼承父類而不必實現(xiàn)每一種方法

那么一個很關(guān)鍵的問題來了,對于多繼承,我們該怎么辦呢,如何準備呢

是否可以繼承多個類

如果繼承多個類每個類中定義了相同的函數(shù),那么哪一個會被使用呢

1、Python的類可以繼承多個類,Java和C#中則只能繼承一個類

2、Python的類如果繼承了多個類,那么其尋找方法的方式有兩種,分別是:深度優(yōu)先和廣度優(yōu)先

對深度優(yōu)先和廣度優(yōu)先的詳解請見附錄:

當類是經(jīng)典類的時候,多繼承情況下,會按照深度優(yōu)先方式查找

當類是新式類的時候,多繼承情況下,會按照廣度優(yōu)先方式查找

區(qū)分:當前類或者父類繼承了object類,那么該類便是新式類,否則是經(jīng)典類

class C1: #C1是經(jīng)典類

? ? pass

class C2(object)#C1是經(jīng)典類

? ? 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()

#?執(zhí)行bar方法時#?首先去A類中查找,如果A類中沒有,則繼續(xù)去B類中找,如果B類中么有,則繼續(xù)去C類中找,如果C類中么有,則繼續(xù)去D類中找,如果還是未找到,則報錯#?所以,查找順序:A?-->?B?-->?C?-->?D#?在上述查找bar方法的過程中,一旦找到,則尋找過程立即中斷,便不會再繼續(xù)找了經(jīng)典類:首先去A類中查找,如果A類中沒有,則繼續(xù)去B類中找,如果B類中么有,則繼續(xù)去D類中找,如果D類中么有,則繼續(xù)去C類中找,如果還是未找到,則報錯 新式類:首先去A類中查找,如果A類中沒有,則繼續(xù)去B類中找,如果B類中么有,則繼續(xù)去C類中找,如果C類中么有,則繼續(xù)去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):??#?一個接口,多種形態(tài)obj.talk()c1?=?Cat('小晴') d1?=?Dog('李磊')func(c1) func(d1) 正確代碼 Func函數(shù)需要接收一個F1類型或者F1子類的類型"""obj.show()s1_obj?=?S1() Func(s1_obj)?#?在Func函數(shù)中傳入S1類的對象?s1_obj,執(zhí)行?S1?的show方法,結(jié)果:S1.shows2_obj?=?S2() Func(s2_obj)?#?在Func函數(shù)中傳入Ss類的對象?ss_obj,執(zhí)行?Ss?的show方法,結(jié)果:S2.show復(fù)制代碼class?F1:passclass?S1(F1):def?show(self):print'S1.show'class?S2(F1):def?show(self):print'S2.show'#?由于在Java或C#中定義函數(shù)參數(shù)時,必須指定參數(shù)的類型 #?為了讓Func函數(shù)既可以執(zhí)行S1對象的show方法,又可以執(zhí)行S2對象的show方法,所以,定義了一個S1和S2類的父類 #?而實際傳入的參數(shù)是:S1對象和S2對象def?Func(F1?obj): """Func函數(shù)需要接收一個F1類型或者F1子類的類型"""print(obj.show())s1_obj?=?S1() Func(s1_obj)??#?在Func函數(shù)中傳入S1類的對象?s1_obj,執(zhí)行?S1?的show方法,結(jié)果:S1.shows2_obj?=?S2() Func(s2_obj)??#?在Func函數(shù)中傳入Ss類的對象?ss_obj,執(zhí)行?Ss?的show方法,結(jié)果:S2.show 錯誤代碼,版本不對

深度優(yōu)先和廣度優(yōu)先會在爬蟲等多個領(lǐng)域進行運用

第一詳解:

深度優(yōu)先算法:

(1)訪問初始頂點v并標記頂點v已訪問。
(2)查找頂點v的第一個鄰接頂點w。
(3)若頂點v的鄰接頂點w存在,則繼續(xù)執(zhí)行;否則回溯到v,再找v的另外一個未訪問過的鄰接點。
(4)若頂點w尚未被訪問,則訪問頂點w并標記頂點w為已訪問。
(5)繼續(xù)查找頂點w的下一個鄰接頂點wi,如果v取值wi轉(zhuǎn)到步驟(3)。直到連通圖中所有頂點全部訪問過為止。

廣度優(yōu)先算法:

(1)頂點v入隊列。
(2)當隊列非空時則繼續(xù)執(zhí)行,否則算法結(jié)束。
(3)出隊列取得隊頭頂點v;訪問頂點v并標記頂點v已被訪問。
(4)查找頂點v的第一個鄰接頂點col。
(5)若v的鄰接頂點col未被訪問過的,則col入隊列。
(6)繼續(xù)查找頂點v的另一個新的鄰接頂點col,轉(zhuǎn)到步驟(5)。直到頂點v的所有未被訪問過的鄰接點處理完。轉(zhuǎn)到步驟(2)。


第二詳解:

深度優(yōu)先是指網(wǎng)絡(luò)爬蟲會從起始頁開始,一個鏈接一個鏈接跟蹤下去,處理完這條線路之后再轉(zhuǎn)入下一個起始頁,繼續(xù)追蹤鏈接,通過下圖進行理解:

注:scrapy默認采用的是深度優(yōu)先算法

A-B-D-E-I-C-F-G-H (遞歸實現(xiàn))

廣度優(yōu)先,有人也叫寬度優(yōu)先,是指將新下載網(wǎng)頁發(fā)現(xiàn)的鏈接直接插入到待抓取URL隊列的末尾,也就是指網(wǎng)絡(luò)爬蟲會先抓取起始頁中的所有網(wǎng)頁,然后在選擇其中的一個連接網(wǎng)頁,繼續(xù)抓取在此網(wǎng)頁中鏈接的所有網(wǎng)頁,通過下圖進行理解:

A-B-C-D-E-F-G-H-I (隊列實現(xiàn))



? ? ? 本文轉(zhuǎn)自眉間雪 51CTO博客,原文鏈接:http://blog.51cto.com/13348847/1980015,如需轉(zhuǎn)載請自行聯(lián)系原作者





總結(jié)

以上是生活随笔為你收集整理的python面向对象基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。