最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

談一談基于python的面向?qū)ο缶幊袒A(chǔ)

 更新時(shí)間:2019年05月21日 17:00:07   投稿:laozhang  
在本篇內(nèi)容中我們給大家整理了關(guān)于python面向?qū)ο缶幊袒A(chǔ)的觀點(diǎn)分析以及知識(shí)點(diǎn)整理,有需要的朋友們學(xué)習(xí)下。

活在當(dāng)下的程序員應(yīng)該都聽(tīng)過(guò)“面向?qū)ο缶幊獭币辉~,也經(jīng)常有人問(wèn)能不能用一句話解釋下什么是“面向?qū)ο缶幊獭?,我們先?lái)看看比較正式的說(shuō)法。

把一組數(shù)據(jù)結(jié)構(gòu)和處理它們的方法組成對(duì)象(object),把相同行為的對(duì)象歸納為類(lèi)(class),通過(guò)類(lèi)的封裝(encapsulation)隱藏內(nèi)部細(xì)節(jié),通過(guò)繼承(inheritance)實(shí)現(xiàn)類(lèi)的特化(specialization)和泛化(generalization),通過(guò)多態(tài)(polymorphism)實(shí)現(xiàn)基于對(duì)象類(lèi)型的動(dòng)態(tài)分派。

這樣一說(shuō)是不是更不明白了。所以我們還是看看更通俗易懂的說(shuō)法,下面這段內(nèi)容來(lái)自于知乎。

說(shuō)明: 以上的內(nèi)容來(lái)自于網(wǎng)絡(luò),不代表作者本人的觀點(diǎn)和看法,與作者本人立場(chǎng)無(wú)關(guān),相關(guān)責(zé)任不由作者承擔(dān)。

之前我們說(shuō)過(guò)“程序是指令的集合”,我們?cè)诔绦蛑袝?shū)寫(xiě)的語(yǔ)句在執(zhí)行時(shí)會(huì)變成一條或多條指令然后由CPU去執(zhí)行。當(dāng)然為了簡(jiǎn)化程序的設(shè)計(jì),我們引入了函數(shù)的概念,把相對(duì)獨(dú)立且經(jīng)常重復(fù)使用的代碼放置到函數(shù)中,在需要使用這些功能的時(shí)候只要調(diào)用函數(shù)即可;如果一個(gè)函數(shù)的功能過(guò)于復(fù)雜和臃腫,我們又可以進(jìn)一步將函數(shù)繼續(xù)切分為子函數(shù)來(lái)降低系統(tǒng)的復(fù)雜性。但是說(shuō)了這么多,不知道大家是否發(fā)現(xiàn),所謂編程就是程序員按照計(jì)算機(jī)的工作方式控制計(jì)算機(jī)完成各種任務(wù)。但是,計(jì)算機(jī)的工作方式與正常人類(lèi)的思維模式是不同的,如果編程就必須得拋棄人類(lèi)正常的思維方式去迎合計(jì)算機(jī),編程的樂(lè)趣就少了很多,“每個(gè)人都應(yīng)該學(xué)習(xí)編程”這樣的豪言壯語(yǔ)就只能說(shuō)說(shuō)而已。當(dāng)然,這些還不是最重要的,最重要的是當(dāng)我們需要開(kāi)發(fā)一個(gè)復(fù)雜的系統(tǒng)時(shí),代碼的復(fù)雜性會(huì)讓開(kāi)發(fā)和維護(hù)工作都變得舉步維艱,所以在上世紀(jì)60年代末期,“軟件危機(jī)”、“軟件工程”等一系列的概念開(kāi)始在行業(yè)中出現(xiàn)。

當(dāng)然,程序員圈子內(nèi)的人都知道,現(xiàn)實(shí)中并沒(méi)有解決上面所說(shuō)的這些問(wèn)題的“銀彈”,真正讓軟件開(kāi)發(fā)者看到希望的是上世紀(jì)70年代誕生的Smalltalk編程語(yǔ)言中引入的面向?qū)ο蟮木幊趟枷耄嫦驅(qū)ο缶幊痰碾r形可以追溯到更早期的Simula語(yǔ)言)。按照這種編程理念,程序中的數(shù)據(jù)和操作數(shù)據(jù)的函數(shù)是一個(gè)邏輯上的整體,我們稱之為“對(duì)象”,而我們解決問(wèn)題的方式就是創(chuàng)建出需要的對(duì)象并向?qū)ο蟀l(fā)出各種各樣的消息,多個(gè)對(duì)象的協(xié)同工作最終可以讓我們構(gòu)造出復(fù)雜的系統(tǒng)來(lái)解決現(xiàn)實(shí)中的問(wèn)題。

說(shuō)明: 當(dāng)然面向?qū)ο笠膊皇墙鉀Q軟件開(kāi)發(fā)中所有問(wèn)題的最后的“銀彈”,所以今天的高級(jí)程序設(shè)計(jì)語(yǔ)言幾乎都提供了對(duì)多種編程范式的支持,Python也不例外。

類(lèi)和對(duì)象

簡(jiǎn)單的說(shuō),類(lèi)是對(duì)象的藍(lán)圖和模板,而對(duì)象是類(lèi)的實(shí)例。這個(gè)解釋雖然有點(diǎn)像用概念在解釋概念,但是從這句話我們至少可以看出,類(lèi)是抽象的概念,而對(duì)象是具體的東西。在面向?qū)ο缶幊痰氖澜缰?,一切皆為?duì)象,對(duì)象都有屬性和行為,每個(gè)對(duì)象都是獨(dú)一無(wú)二的,而且對(duì)象一定屬于某個(gè)類(lèi)(型)。當(dāng)我們把一大堆擁有共同特征的對(duì)象的靜態(tài)特征(屬性)和動(dòng)態(tài)特征(行為)都抽取出來(lái)后,就可以定義出一個(gè)叫做“類(lèi)”的東西。

定義類(lèi)

在Python中可以使用class關(guān)鍵字定義類(lèi),然后在類(lèi)中通過(guò)之前學(xué)習(xí)過(guò)的函數(shù)來(lái)定義方法,這樣就可以將對(duì)象的動(dòng)態(tài)特征描述出來(lái),代碼如下所示。

class Student(object):

 # __init__是一個(gè)特殊方法用于在創(chuàng)建對(duì)象時(shí)進(jìn)行初始化操作
 # 通過(guò)這個(gè)方法我們可以為學(xué)生對(duì)象綁定name和age兩個(gè)屬性
 def __init__(self, name, age):
  self.name = name
  self.age = age

 def study(self, course_name):
  print('%s正在學(xué)習(xí)%s.' % (self.name, course_name))

 # PEP 8要求標(biāo)識(shí)符的名字用全小寫(xiě)多個(gè)單詞用下劃線連接
 # 但是很多程序員和公司更傾向于使用駝峰命名法(駝峰標(biāo)識(shí))
 def watch_av(self):
  if self.age < 18:
   print('%s只能觀看《熊出沒(méi)》.' % self.name)
  else:
   print('%s正在觀看島國(guó)愛(ài)情動(dòng)作片.' % self.name)

說(shuō)明: 寫(xiě)在類(lèi)中的函數(shù),我們通常稱之為(對(duì)象的)方法,這些方法就是對(duì)象可以接收的消息。

創(chuàng)建和使用對(duì)象

當(dāng)我們定義好一個(gè)類(lèi)之后,可以通過(guò)下面的方式來(lái)創(chuàng)建對(duì)象并給對(duì)象發(fā)消息。

def main():
 # 創(chuàng)建學(xué)生對(duì)象并指定姓名和年齡
 stu1 = Student('駱昊', 38)
 # 給對(duì)象發(fā)study消息
 stu1.study('Python程序設(shè)計(jì)')
 # 給對(duì)象發(fā)watch_av消息
 stu1.watch_av()
 stu2 = Student('王大錘', 15)
 stu2.study('思想品德')
 stu2.watch_av()


if __name__ == '__main__':
 main()

訪問(wèn)可見(jiàn)性問(wèn)題

對(duì)于上面的代碼,有C++、Java、C#等編程經(jīng)驗(yàn)的程序員可能會(huì)問(wèn),我們給Student對(duì)象綁定的name和age屬性到底具有怎樣的訪問(wèn)權(quán)限(也稱為可見(jiàn)性)。因?yàn)樵诤芏嗝嫦驅(qū)ο缶幊陶Z(yǔ)言中,我們通常會(huì)將對(duì)象的屬性設(shè)置為私有的(private)或受保護(hù)的(protected),簡(jiǎn)單的說(shuō)就是不允許外界訪問(wèn),而對(duì)象的方法通常都是公開(kāi)的(public),因?yàn)楣_(kāi)的方法就是對(duì)象能夠接受的消息。在Python中,屬性和方法的訪問(wèn)權(quán)限只有兩種,也就是公開(kāi)的和私有的,如果希望屬性是私有的,在給屬性命名時(shí)可以用兩個(gè)下劃線作為開(kāi)頭,下面的代碼可以驗(yàn)證這一點(diǎn)。

class Test:

 def __init__(self, foo):
  self.__foo = foo

 def __bar(self):
  print(self.__foo)
  print('__bar')


def main():
 test = Test('hello')
 # AttributeError: 'Test' object has no attribute '__bar'
 test.__bar()
 # AttributeError: 'Test' object has no attribute '__foo'
 print(test.__foo)


if __name__ == "__main__":
 main()

但是,Python并沒(méi)有從語(yǔ)法上嚴(yán)格保證私有屬性或方法的私密性,它只是給私有的屬性和方法換了一個(gè)名字來(lái)“妨礙”對(duì)它們的訪問(wèn),事實(shí)上如果你知道更換名字的規(guī)則仍然可以訪問(wèn)到它們,下面的代碼就可以驗(yàn)證這一點(diǎn)。之所以這樣設(shè)定,可以用這樣一句名言加以解釋?zhuān)褪恰癢e are all consenting adults here”。因?yàn)榻^大多數(shù)程序員都認(rèn)為開(kāi)放比封閉要好,而且程序員要自己為自己的行為負(fù)責(zé)。

class Test:

 def __init__(self, foo):
  self.__foo = foo

 def __bar(self):
  print(self.__foo)
  print('__bar')


def main():
 test = Test('hello')
 test._Test__bar()
 print(test._Test__foo)


if __name__ == "__main__":
 main()

在實(shí)際開(kāi)發(fā)中,我們并不建議將屬性設(shè)置為私有的,因?yàn)檫@會(huì)導(dǎo)致子類(lèi)無(wú)法訪問(wèn)(后面會(huì)講到)。所以大多數(shù)Python程序員會(huì)遵循一種命名慣例就是讓屬性名以單下劃線開(kāi)頭來(lái)表示屬性是受保護(hù)的,本類(lèi)之外的代碼在訪問(wèn)這樣的屬性時(shí)應(yīng)該要保持慎重。這種做法并不是語(yǔ)法上的規(guī)則,單下劃線開(kāi)頭的屬性和方法外界仍然是可以訪問(wèn)的,所以更多的時(shí)候它是一種暗示或隱喻

面向?qū)ο蟮闹е?/strong>

面向?qū)ο笥腥笾е悍庋b、繼承和多態(tài)。后面兩個(gè)概念在下一個(gè)章節(jié)中進(jìn)行詳細(xì)的說(shuō)明,這里我們先說(shuō)一下什么是封裝。我自己對(duì)封裝的理解是“隱藏一切可以隱藏的實(shí)現(xiàn)細(xì)節(jié),只向外界暴露(提供)簡(jiǎn)單的編程接口”。我們?cè)陬?lèi)中定義的方法其實(shí)就是把數(shù)據(jù)和對(duì)數(shù)據(jù)的操作封裝起來(lái)了,在我們創(chuàng)建了對(duì)象之后,只需要給對(duì)象發(fā)送一個(gè)消息(調(diào)用方法)就可以執(zhí)行方法中的代碼,也就是說(shuō)我們只需要知道方法的名字和傳入的參數(shù)(方法的外部視圖),而不需要知道方法內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)(方法的內(nèi)部視圖)。

練習(xí)

練習(xí)1:定義一個(gè)類(lèi)描述數(shù)字時(shí)鐘

class Clock(object):
 """數(shù)字時(shí)鐘"""

 def __init__(self, hour=0, minute=0, second=0):
  """初始化方法

  :param hour: 時(shí)
  :param minute: 分
  :param second: 秒
  """
  self._hour = hour
  self._minute = minute
  self._second = second

 def run(self):
  """走字"""
  self._second += 1
  if self._second == 60:
   self._second = 0
   self._minute += 1
   if self._minute == 60:
    self._minute = 0
    self._hour += 1
    if self._hour == 24:
     self._hour = 0

 def show(self):
  """顯示時(shí)間"""
  return '%02d:%02d:%02d' % \
    (self._hour, self._minute, self._second)


def main():
 clock = Clock(23, 59, 58)
 while True:
  print(clock.show())
  sleep(1)
  clock.run()


if __name__ == '__main__':
 main()

練習(xí)2:定義一個(gè)類(lèi)描述平面上的點(diǎn)并提供移動(dòng)點(diǎn)和計(jì)算到另一個(gè)點(diǎn)距離的方法。

from math import sqrt


class Point(object):

 def __init__(self, x=0, y=0):
  """初始化方法
  
  :param x: 橫坐標(biāo)
  :param y: 縱坐標(biāo)
  """
  self.x = x
  self.y = y

 def move_to(self, x, y):
  """移動(dòng)到指定位置
  
  :param x: 新的橫坐標(biāo)
  "param y: 新的縱坐標(biāo)
  """
  self.x = x
  self.y = y

 def move_by(self, dx, dy):
  """移動(dòng)指定的增量
  
  :param dx: 橫坐標(biāo)的增量
  "param dy: 縱坐標(biāo)的增量
  """
  self.x += dx
  self.y += dy

 def distance_to(self, other):
  """計(jì)算與另一個(gè)點(diǎn)的距離
  
  :param other: 另一個(gè)點(diǎn)
  """
  dx = self.x - other.x
  dy = self.y - other.y
  return sqrt(dx ** 2 + dy ** 2)

 def __str__(self):
  return '(%s, %s)' % (str(self.x), str(self.y))


def main():
 p1 = Point(3, 5)
 p2 = Point()
 print(p1)
 print(p2)
 p2.move_by(-1, 2)
 print(p2)
 print(p1.distance_to(p2))


if __name__ == '__main__':
 main()

說(shuō)明: 本章中的插圖來(lái)自于Grady Booch等著作的《面向?qū)ο蠓治雠c設(shè)計(jì)》一書(shū),該書(shū)是講解面向?qū)ο缶幊痰慕?jīng)典著作,有興趣的讀者可以購(gòu)買(mǎi)和閱讀這本書(shū)來(lái)了解更多的面向?qū)ο蟮南嚓P(guān)知識(shí)。

相關(guān)文章

  • Python實(shí)現(xiàn)對(duì)相同數(shù)據(jù)分箱的小技巧分享

    Python實(shí)現(xiàn)對(duì)相同數(shù)據(jù)分箱的小技巧分享

    這篇文章主要給大家介紹了關(guān)于Python實(shí)現(xiàn)對(duì)相同數(shù)據(jù)分箱的小技巧,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-01-01
  • Python Scrapy多頁(yè)數(shù)據(jù)爬取實(shí)現(xiàn)過(guò)程解析

    Python Scrapy多頁(yè)數(shù)據(jù)爬取實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了Python Scrapy多頁(yè)數(shù)據(jù)爬取實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Python tkinter事件高級(jí)用法實(shí)例

    Python tkinter事件高級(jí)用法實(shí)例

    這篇文章主要介紹了Python tkinter事件高級(jí)用法,結(jié)合實(shí)例形式分析了Python使用tkinter模塊的事件響應(yīng)及圖形繪制相關(guān)操作技巧,需要的朋友可以參考下
    2018-01-01
  • Tensorflow使用支持向量機(jī)擬合線性回歸

    Tensorflow使用支持向量機(jī)擬合線性回歸

    這篇文章主要為大家詳細(xì)介紹了Tensorflow使用支持向量機(jī)擬合線性回歸,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • Python生成直方圖方法實(shí)現(xiàn)詳解

    Python生成直方圖方法實(shí)現(xiàn)詳解

    這篇文章主要介紹了python OpenCV圖像直方圖處理,文章通過(guò)matplotlib畫(huà)一個(gè)直方圖展開(kāi)詳情,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-11-11
  • Windows系統(tǒng)下實(shí)現(xiàn)pycharm運(yùn)行.sh文件(本地運(yùn)行和打開(kāi)服務(wù)器終端)

    Windows系統(tǒng)下實(shí)現(xiàn)pycharm運(yùn)行.sh文件(本地運(yùn)行和打開(kāi)服務(wù)器終端)

    PyCharm是Python開(kāi)發(fā)的高效率IDE,但是很多時(shí)候需要同時(shí)開(kāi)發(fā)Bash(shell)腳本,下面這篇文章主要給大家介紹了關(guān)于Windows系統(tǒng)下實(shí)現(xiàn)pycharm運(yùn)行.sh文件(本地運(yùn)行和打開(kāi)服務(wù)器終端)的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • Python生成可執(zhí)行文件.exe操作完整流程記錄

    Python生成可執(zhí)行文件.exe操作完整流程記錄

    .exe是文件擴(kuò)展名,帶有.exe擴(kuò)展名的文件名按下Enter鍵就可運(yùn)行,這篇文章主要給大家介紹了關(guān)于Python生成可執(zhí)行文件.exe操作完整流程的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • 如何在ubuntu中切換使用不同版本的python

    如何在ubuntu中切換使用不同版本的python

    在ubuntu環(huán)境下進(jìn)行嵌入式開(kāi)發(fā),我們?cè)谶M(jìn)行不同的項(xiàng)目開(kāi)發(fā)時(shí),可能會(huì)遇到python環(huán)境不統(tǒng)一的情況,下面這篇文章主要給大家介紹了關(guān)于如何在ubuntu中切換使用不同版本的python的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • 使用Numpy讀取CSV文件,并進(jìn)行行列刪除的操作方法

    使用Numpy讀取CSV文件,并進(jìn)行行列刪除的操作方法

    今天小編就為大家分享一篇使用Numpy讀取CSV文件,并進(jìn)行行列刪除的操作方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Python模塊介紹與使用詳細(xì)講解

    Python模塊介紹與使用詳細(xì)講解

    這篇文章主要介紹了Python模塊介紹與使用詳細(xì)講解,包括模塊的相關(guān)概念和使用方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04

最新評(píng)論

寻甸| 青浦区| 阜新| 宜宾市| 加查县| 香港 | 隆昌县| 青岛市| 札达县| 天气| 凌海市| 高淳县| 民勤县| 元朗区| 永寿县| 大新县| 资溪县| 临颍县| 龙游县| 民丰县| 荆门市| 沁源县| 中西区| 济源市| 华容县| 额济纳旗| 鸡东县| 皮山县| 江山市| 双江| 洪泽县| 九寨沟县| 当雄县| 金平| 冀州市| 盐亭县| 收藏| 金坛市| 普安县| 汾西县| 五常市|