中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python面向對象編程怎么理解

發布時間:2021-11-30 15:17:38 來源:億速云 閱讀:228 作者:iii 欄目:開發技術

本篇內容主要講解“Python面向對象編程怎么理解”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Python面向對象編程怎么理解”吧!

面向對象編程是一種非常流行的編程范式(programming paradigm),所謂編程范式就是程序設計的方法學,也就是程序員對程序的認知和理解。

類和對象

如果要用一句話來概括面向對象編程,我認為下面的說法是相當精準的。

面向對象編程:把一組數據和處理數據的方法組成對象,把行為相同的對象歸納為類,通過封裝隱藏對象的內部細節,通過繼承實現類的特化和泛化,通過多態實現基于對象類型的動態分派。

這句話對初學者來說可能難以理解,但是我們先為大家圈出幾個關鍵詞:對象(object)、類(class)、封裝(encapsulation)、繼承(inheritance)、多態(polymorphism)。

我們先說說類和對象這兩個詞。在面向對象編程中,類是一個抽象的概念,對象是一個具體的概念。我們把同一類對象的共同特征抽取出來就是一個類,比如我們經常說的人類,這是一個抽象概念,而我們每個人就是人類的這個抽象概念下的具體的實實在在的存在,也就是一個對象。簡而言之,類是對象的藍圖和模板,對象是類的實例。

在面向對象編程的世界中,一切皆為對象,對象都有屬性和行為,每個對象都是獨一無二的,而且對象一定屬于某個類。對象的屬性是對象的靜態特征,對象的行為是對象的動態特征。按照上面的說法,如果我們把擁有共同特征的對象的屬性和行為都抽取出來,就可以定義出一個類。

定義類

在Python中,可以使用class關鍵字加上類名來定義類,通過縮進我們可以確定類的代碼塊,就如同定義函數那樣。在類的代碼塊中,我們需要寫一些函數,我們說過類是一個抽象概念,那么這些函數就是我們對一類對象共同的動態特征的提取。寫在類里面的函數我們通常稱之為方法,方法就是對象的行為,也就是對象可以接收的消息。方法的第一個參數通常都是self,它代表了接收這個消息的對象本身。

class Student:

   def study(self, course_name):
       print(f'學生正在學習{course_name}.')

   def play(self):
       print(f'學生正在玩游戲.')

創建和使用對象

在我們定義好一個類之后,可以使用構造器語法來創建對象,代碼如下所示。

stu1 = Student()
stu2 = Student()
print(stu1)    # <__main__.Student object at 0x10ad5ac50>
print(stu2)    # <__main__.Student object at 0x10ad5acd0>
print(hex(id(stu1)), hex(id(stu2)))    # 0x10ad5ac50 0x10ad5acd0

在類的名字后跟上圓括號就是所謂的構造器語法,上面的代碼創建了兩個學生對象,一個賦值給變量stu1,一個復制給變量stu2。當我們用print函數打印stu1和stu2兩個變量時,我們會看到輸出了對象在內存中的地址(十六進制形式),跟我們用id函數查看對象標識獲得的值是相同的。現在我們可以告訴大家,我們定義的變量其實保存的是一個對象在內存中的邏輯地址(位置),通過這個邏輯地址,我們就可以在內存中找到這個對象。所以stu3 = stu2這樣的賦值語句并沒有創建新的對象,只是用一個新的變量保存了已有對象的地址。

接下來,我們嘗試給對象發消息,即調用對象的方法。剛才的Student類中我們定義了study和play兩個方法,兩個方法的第一個參數self代表了接收消息的學生對象,study方法的第二個參數是學習的課程名稱。Python中,給對象發消息有兩種方式,請看下面的代碼。

# 通過“類.方法”調用方法,第一個參數是接收消息的對象,第二個參數是學習的課程名稱
Student.study(stu1, 'Python程序設計')    # 學生正在學習Python程序設計.
# 通過“對象.方法”調用方法,點前面的對象就是接收消息的對象,只需要傳入第二個參數
stu1.study('Python程序設計')             # 學生正在學習Python程序設計.

Student.play(stu2)    # 學生正在玩游戲.
stu2.play()           # 學生正在玩游戲.

初始化方法

大家可能已經注意到了,剛才我們創建的學生對象只有行為沒有屬性,如果要給學生對象定義屬性,我們可以修改Student類,為其添加一個名為__init__的方法。在我們調用Student類的構造器創建對象時,首先會在內存中獲得保存學生對象所需的內存空間,然后通過自動執行__init__方法,完成對內存的初始化操作,也就是把數據放到內存空間中。所以我們可以通過給Student類添加__init__方法的方式為學生對象指定屬性,同時完成對屬性賦初始值的操作,正因如此,__init__方法通常也被稱為初始化方法。

我們對上面的Student類稍作修改,給學生對象添加name(姓名)和age(年齡)兩個屬性。

class Student:
   """學生"""

   def __init__(self, name, age):
       """初始化方法"""
       self.name = name
       self.age = age

   def study(self, course_name):
       """學習"""
       print(f'{self.name}正在學習{course_name}.')

   def play(self):
       """玩耍"""
       print(f'{self.name}正在玩游戲.')

修改剛才創建對象和給對象發消息的代碼,重新執行一次,看看程序的執行結果有什么變化。

# 由于初始化方法除了self之外還有兩個參數
# 所以調用Student類的構造器創建對象時要傳入這兩個參數
stu1 = Student('駱昊', 40)
stu2 = Student('王大錘', 15)
stu1.study('Python程序設計')    # 駱昊正在學習Python程序設計.
stu2.play()                    # 王大錘正在玩游戲.

打印對象

上面我們通過__init__方法在創建對象時為對象綁定了屬性并賦予了初始值。在Python中,以兩個下劃線__(讀作“dunder”)開頭和結尾的方法通常都是有特殊用途和意義的方法,我們一般稱之為魔術方法或魔法方法。如果我們在打印對象的時候不希望看到對象的地址而是看到我們自定義的信息,可以通過在類中放置__repr__魔術方法來做到,該方法返回的字符串就是用print函數打印對象的時候會顯示的內容,代碼如下所示。

class Student:
   """學生"""

   def __init__(self, name, age):
       """初始化方法"""
       self.name = name
       self.age = age

   def study(self, course_name):
       """學習"""
       print(f'{self.name}正在學習{course_name}.')

   def play(self):
       """玩耍"""
       print(f'{self.name}正在玩游戲.')

   def __repr__(self):
       return f'{self.name}: {self.age}'stu1 = Student('駱昊', 40)
print(stu1)        # 駱昊: 40
students = [stu1, Student('王小錘', 16), Student('王大錘', 25)]
print(students)    # [駱昊: 40, 王小錘: 16, 王大錘: 25]

面向對象的支柱

面向對象編程有三大支柱,就是我們之前給大家劃重點的時候圈出的三個詞:封裝、繼承和多態。后面兩個概念在下一節課中會詳細說明,這里我們先說一下什么是封裝。我自己對封裝的理解是:隱藏一切可以隱藏的實現細節,只向外界暴露簡單的調用接口。我們在類中定義的對象方法其實就是一種封裝,這種封裝可以讓我們在創建對象之后,只需要給對象發送一個消息就可以執行方法中的代碼,也就是說我們在只知道方法的名字和參數(方法的外部視圖),不知道方法內部實現細節(方法的內部視圖)的情況下就完成了對方法的使用。

舉一個例子,假如要控制一個機器人幫我倒杯水,如果不使用面向對象編程,不做任何的封裝,那么就需要向這個機器人發出一系列的指令,如站起來、向左轉、向前走5步、拿起面前的水杯、向后轉、向前走10步、彎腰、放下水杯、按下出水按鈕、等待10秒、松開出水按鈕、拿起水杯、向右轉、向前走5步、放下水杯等,才能完成這個簡單的操作,想想都覺得麻煩。按照面向對象編程的思想,我們可以將倒水的操作封裝到機器人的一個方法中,當需要機器人幫我們倒水的時候,只需要向機器人對象發出倒水的消息就可以了,這樣做不是更好嗎?

在很多場景下,面向對象編程其實就是一個三步走的問題。第一步定義類,第二步創建對象,第三步給對象發消息。當然,有的時候我們是不需要第一步的,因為我們想用的類可能已經存在了。之前我們說過,Python內置的list、set、dict其實都不是函數而是類,如果要創建列表、集合、字典對象,我們就不用自定義類了。當然,有的類并不是Python標準庫中直接提供的,它可能來自于第三方的代碼,如何安裝和使用三方代碼在后續課程中會進行討論。在某些特殊的場景中,我們會用到名為“內置對象”的對象,所謂“內置對象”就是說上面三步走的第一步和第二步都不需要了,因為類已經存在而且對象已然創建過了,直接向對象發消息就可以了,這也就是我們常說的“開箱即用”。

經典案例

例子1:定義一個類描述數字時鐘。

import time
# 定義數字時鐘類
class Clock(object):
   """數字時鐘"""

   def __init__(self, hour=0, minute=0, second=0):
       """初始化方法
       :param hour: 時
       :param minute: 分
       :param second: 秒
       """
       self.hour = hour
       self.min = minute
       self.sec = second

   def run(self):
       """走字"""
       self.sec += 1
       if self.sec == 60:
           self.sec = 0
           self.min += 1
           if self.min == 60:
               self.min = 0
               self.hour += 1
               if self.hour == 24:
                   self.hour = 0

   def show(self):
       """顯示時間"""
       return f'{self.hour:0>2d}:{self.min:0>2d}:{self.sec:0>2d}' # 創建時鐘對象
clock = Clock(23, 59, 58)
while True:
   # 給時鐘對象發消息讀取時間
   print(clock.show())
   # 休眠1秒鐘
   time.sleep(1)
   # 給時鐘對象發消息使其走字
   clock.run()

例子2:定義一個類描述平面上的點,要求提供計算到另一個點距離的方法。

class Point(object):
   """屏面上的點"""

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

   def distance_to(self, other):
       """計算與另一個點的距離
       :param other: 另一個點
       """
       dx = self.x - other.x
       dy = self.y - other.y
       return (dx * dx + dy * dy) ** 0.5

   def __str__(self):
       return f'({self.x}, {self.y})'p1 = Point(3, 5)
p2 = Point(6, 9)
print(p1, p2)
print(p1.distance_to(p2))

到此,相信大家對“Python面向對象編程怎么理解”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

聊城市| 平利县| 黑山县| 利川市| 疏勒县| 公安县| 报价| 衡阳市| 灵丘县| 郎溪县| 沅江市| 龙海市| 温泉县| 全椒县| 行唐县| 含山县| 内乡县| 鲁甸县| 个旧市| 中卫市| 牡丹江市| 辰溪县| 大悟县| 名山县| 清涧县| 金平| 庄浪县| 斗六市| 剑河县| 三门峡市| 百色市| 敦化市| 通榆县| 托里县| 富民县| 长兴县| 阜平县| 新田县| 麟游县| 郸城县| 旬阳县|