1. 程式人生 > 實用技巧 >python基礎--面向物件(基礎)

python基礎--面向物件(基礎)

一. 理解面向物件

面向物件是一種抽象化的程式設計思想,很多程式語言中都有的一種思想。

總結:面向物件就是將程式設計當成是一個事物,對外界來說,事物是直接使用的,不用去管他內部的情況。而程式設計就是設定事物能夠做什麼事。

二. 類和物件

類和物件的關係:用類去建立一個物件。

2.1 理解類和物件

2.1.1 類

類是對一系列具有相同特徵行為的事物的統稱,是一個抽象的概念,不是真實存在的事物。

  • 特徵即是屬性
  • 行為即是方法

類比如是製造洗衣機時要用到的圖紙,也就是說類是用來建立物件

2.1.2 物件

物件是類創建出來的真實存在的事物,例如:洗衣機。

注意:開發中,先有類,再有物件。

2.2 面向物件實現方法

2.2.1 定義類

Python2中類分為:經典類 和 新式類

  • 語法
class 類名():
    程式碼
    ......

注意:類名要滿足識別符號命名規則,同時遵循大駝峰命名習慣

  • 體驗
class Washer():
    def wash(self):
        print('我會洗衣服')
  • 拓展:經典類

不由任意內建型別派生出的類,稱之為經典類

class 類名:
    程式碼
    ......

2.2.2 建立物件

物件又名例項。

  • 語法
物件名 = 類名()
  • 體驗
# 建立物件
haier1 = Washer()

# <__main__.Washer object at 0x0000018B7B224240>
print(haier1)

# haier物件呼叫例項方法
haier1.wash()

注意:建立物件的過程也叫例項化物件。

2.2.3 self

self指的是呼叫該函式的物件。

# 1. 定義類
class Washer():
    def wash(self):
        print('我會洗衣服')
        # <__main__.Washer object at 0x0000024BA2B34240>
        print(self)


# 2. 建立物件
haier1 = Washer()
# <__main__.Washer object at 0x0000018B7B224240>
print(haier1)
# haier1物件呼叫例項方法
haier1.wash()


haier2 = Washer()
# <__main__.Washer object at 0x0000022005857EF0>
print(haier2)

注意:列印物件和self得到的結果是一致的,都是當前物件的記憶體中儲存地址。

三. 新增和獲取物件屬性

屬性即是特徵,比如:洗衣機的寬度、高度、重量...

物件屬性既可以在類外面新增和獲取,也能在類裡面新增和獲取。

3.1 類外面新增物件屬性

  • 語法
物件名.屬性名 = 值
  • 體驗
haier1.width = 500
haier1.height = 800

3.2 類外面獲取物件屬性

  • 語法
物件名.屬性名
  • 體驗
print(f'haier1洗衣機的寬度是{haier1.width}')
print(f'haier1洗衣機的高度是{haier1.height}')

3.3 類裡面獲取物件屬性

  • 語法
self.屬性名
  • 體驗
# 定義類
class Washer():
    def print_info(self):
        # 類裡面獲取例項屬性
        print(f'haier1洗衣機的寬度是{self.width}')
        print(f'haier1洗衣機的高度是{self.height}')

# 建立物件
haier1 = Washer()

# 新增例項屬性
haier1.width = 500
haier1.height = 800

haier1.print_info()

四. 魔法方法

在Python中,__xx__()的函式叫做魔法方法,指的是具有特殊功能的函式。

4.1 __init__()

4.1.1 體驗__init__()

思考:洗衣機的寬度高度是與生俱來的屬性,可不可以在生產過程中就賦予這些屬性呢?

答:理應如此。

__init__()方法的作用:初始化物件。

class Washer():
    
    # 定義初始化功能的函式
    def __init__(self):
        # 新增例項屬性
        self.width = 500
        self.height = 800


    def print_info(self):
        # 類裡面呼叫例項屬性
        print(f'洗衣機的寬度是{self.width}, 高度是{self.height}')


haier1 = Washer()
haier1.print_info()

注意:

  • __init__()方法,在建立一個物件時預設被呼叫,不需要手動呼叫
  • __init__(self)中的self引數,不需要開發者傳遞,python直譯器會自動把當前的物件引用傳遞過去。

4.1.2 帶引數的__init__()

思考:一個類可以建立多個物件,如何對不同的物件設定不同的初始化屬性呢?

答:傳引數。

class Washer():
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def print_info(self):
        print(f'洗衣機的寬度是{self.width}')
        print(f'洗衣機的高度是{self.height}')


haier1 = Washer(10, 20)
haier1.print_info()


haier2 = Washer(30, 40)
haier2.print_info()

4.2 __str__()

當使用print輸出物件的時候,預設列印物件的記憶體地址。如果類定義了__str__方法,那麼就會列印從在這個方法中 return 的資料。

class Washer():
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def __str__(self):
        return '這是海爾洗衣機的說明書'


haier1 = Washer(10, 20)
# 這是海爾洗衣機的說明書
print(haier1)

4.3 __del__()

當刪除物件時,python直譯器也會預設呼叫__del__()方法。

class Washer():
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def __del__(self):
        print(f'{self}物件已經被刪除')


haier1 = Washer(10, 20)

# <__main__.Washer object at 0x0000026118223278>物件已經被刪除
del haier1

五. 綜合應用

5.1 烤地瓜

5.1.1 需求

需求主線:

  1. 被烤的時間和對應的地瓜狀態:

    0-3分鐘:生的

    3-5分鐘:半生不熟

    5-8分鐘:熟的

    超過8分鐘:烤糊了

  2. 新增的調料:

    使用者可以按自己的意願新增調料

5.1.2 步驟分析

需求涉及一個事物: 地瓜,故案例涉及一個類:地瓜類。

5.1.2.1 定義類

  • 地瓜的屬性

    • 被烤的時間
    • 地瓜的狀態
    • 新增的調料
  • 地瓜的方法

    • 被烤
      • 使用者根據意願設定每次烤地瓜的時間
      • 判斷地瓜被烤的總時間是在哪個區間,修改地瓜狀態
    • 新增調料
      • 使用者根據意願設定新增的調料
      • 將使用者新增的調料儲存
  • 顯示物件資訊

5.1.2.2 建立物件,呼叫相關例項方法

5.1.3 程式碼實現

5.1.3.1 定義類

  • 地瓜屬性
    • 定義地瓜初始化屬性,後期根據程式推進更新例項屬性
class SweetPotato():
    def __init__(self):
        # 被烤的時間
        self.cook_time = 0
        # 地瓜的狀態
        self.cook_static = '生的'
        # 調料列表
        self.condiments = []

5.1.3.2 定義烤地瓜方法

class SweetPotato():
    ......
    
    def cook(self, time):
        """烤地瓜的方法"""
        self.cook_time += time
        if 0 <= self.cook_time < 3:
            self.cook_static = '生的'
        elif 3 <= self.cook_time < 5:
            self.cook_static = '半生不熟'
        elif 5 <= self.cook_time < 8:
            self.cook_static = '熟了'
        elif self.cook_time >= 8:
            self.cook_static = '烤糊了'

5.1.3.3 書寫str魔法方法,用於輸出物件狀態

class SweetPotato():
		......

    def __str__(self):
        return f'這個地瓜烤了{self.cook_time}分鐘, 狀態是{self.cook_static}'

5.1.3.4 建立物件,測試例項屬性和例項方法

digua1 = SweetPotato()
print(digua1)
digua1.cook(2)
print(digua1)

5.1.3.5 定義新增調料方法,並呼叫該例項方法

class SweetPotato():
		......

    def add_condiments(self, condiment):
        """新增調料"""
        self.condiments.append(condiment)
    def __str__(self):
        return f'這個地瓜烤了{self.cook_time}分鐘, 狀態是{self.cook_static}, 新增的調料有{self.condiments}'
      

digua1 = SweetPotato()
print(digua1)

digua1.cook(2)
digua1.add_condiments('醬油')
print(digua1)

digua1.cook(2)
digua1.add_condiments('辣椒麵兒')
print(digua1)

digua1.cook(2)
print(digua1)

digua1.cook(2)
print(digua1)

5.1.4 程式碼總覽

# 定義類
class SweetPotato():
    def __init__(self):
        # 被烤的時間
        self.cook_time = 0
        # 地瓜的狀態
        self.cook_static = '生的'
        # 調料列表
        self.condiments = []

    def cook(self, time):
        """烤地瓜的方法"""
        self.cook_time += time
        if 0 <= self.cook_time < 3:
            self.cook_static = '生的'
        elif 3 <= self.cook_time < 5:
            self.cook_static = '半生不熟'
        elif 5 <= self.cook_time < 8:
            self.cook_static = '熟了'
        elif self.cook_time >= 8:
            self.cook_static = '烤糊了'

    def add_condiments(self, condiment):
        """新增調料"""
        self.condiments.append(condiment)

    def __str__(self):
        return f'這個地瓜烤了{self.cook_time}分鐘, 狀態是{self.cook_static}, 新增的調料有{self.condiments}'


digua1 = SweetPotato()
print(digua1)

digua1.cook(2)
digua1.add_condiments('醬油')
print(digua1)

digua1.cook(2)
digua1.add_condiments('辣椒麵兒')
print(digua1)

digua1.cook(2)
print(digua1)

digua1.cook(2)
print(digua1)

5.2 搬傢俱

5.2.1 需求

將小於房子剩餘面積的傢俱擺放到房子中

5.2.2 步驟分析

需求涉及兩個事物:房子 和 傢俱,故被案例涉及兩個類:房子類 和 傢俱類。

5.2.2.1 定義類

  • 房子類

    • 例項屬性
      • 房子地理位置
      • 房子佔地面積
      • 房子剩餘面積
      • 房子內傢俱列表
    • 例項方法
      • 容納傢俱
    • 顯示房屋資訊
  • 傢俱類

    • 傢俱名稱
    • 傢俱佔地面積

5.2.2.2 建立物件並呼叫相關方法

5.2.3 程式碼實現

5.2.3.1 定義類

  • 傢俱類
class Furniture():
    def __init__(self, name, area):
        # 傢俱名字
        self.name = name
        # 傢俱佔地面積
        self.area = area
  • 房子類

class Home():
    def __init__(self, address, area):
        # 地理位置
        self.address = address
        # 房屋面積
        self.area = area
        # 剩餘面積
        self.free_area = area
        # 傢俱列表
        self.furniture = []

    def __str__(self):
        return f'房子坐落於{self.address}, 佔地面積{self.area}, 剩餘面積{self.free_area}, 傢俱有{self.furniture}'

    def add_furniture(self, item):
        """容納傢俱"""
        if self.free_area >= item.area:
            self.furniture.append(item.name)
            # 傢俱搬入後,房屋剩餘面積 = 之前剩餘面積 - 該傢俱面積
            self.free_area -= item.area
        else:
            print('傢俱太大,剩餘面積不足,無法容納')

5.2.3.2 建立物件並呼叫例項屬性和方法

bed = Furniture('雙人床', 6)
jia1 = Home('北京', 1200)
print(jia1)

jia1.add_furniture(bed)
print(jia1)

sofa = Furniture('沙發', 10)
jia1.add_furniture(sofa)
print(jia1)

ball = Furniture('籃球場', 1500)
jia1.add_furniture(ball)
print(jia1)

六. 總結

  • 面向物件重要組成部分

      • 建立類
    class 類名():
      程式碼
    
    • 物件
    物件名 = 類名()
    
  • 新增物件屬性

    • 類外面
    物件名.屬性名 = 值
    
    • 類裡面
    self.屬性名 = 值
    
  • 獲取物件屬性

    • 類外面
    物件名.屬性名
    
    • 類裡面
    self.屬性名
    
  • 魔法方法

    • __init__(): 初始化
    • __str__():輸出物件資訊
    • __del__():刪除物件時呼叫