蟒蛇書學習筆記——Chapter 09 Section 01 創建和使用類

9.1 創建和使用類

9.1.1 創建Dog類

  根據Dog類創建的每個實例都將存儲名字和年齡,我們賦予了每條小狗蹲下(sit( ))和打滾(roll_over( ))的能力:

class Dog:
    """一次模擬小狗的簡單嘗試"""
    
    def __init__(self, name, age):
        """初始化屬性name和age。"""
        self.name = name
        self.age = age
        
    def sit(self):
        """模擬小狗收到命令蹲下"""
        print(f'{self.name} is now sitting.')
        
    def roll_over(self):
        """模擬小狗收到命令時打滾。"""
        print(f"{self.name} roll over!")

  方法__init__()

   類中的函數稱為方法 。 你在前面學到的有關函數的一切都適用於方法, 就目前而言, 唯一重要的差別是調用方法的方式。 第4行處的方法__init__() 是一個特殊方法, 每當你根據Dog類創建新實例時, Python都會自動運行它。
  在這個方法的名稱中,開頭和末尾各有兩個下劃線,這是一種約定,旨在避免Python默認方法與普通方法發生名稱衝突。務必確保__init__()的兩邊都有兩個下劃線,否則當你使用類來創建實例時,將不會自動調用這個方法,進而引發難以發現的錯誤。
  我們將方法__init__()定義成包含三個形參:self、name和age。在這個方法的定義中,形參self必不可少,而且必須位於其他形參的前面。
  為何必須在方法定義中包含形參self呢? 因為Python調用這個方法來創建Dog實例時,將自動傳入實參self。每個與實例相關聯的方法調用都自動傳遞實參self,它是一個指向實例本身的引用,讓實例能夠訪問類中的屬性和方法。
  創建Dog實例時,Python將調用Dog 類的方法__init__()。我們將通過實參向Dog()傳遞名字和年齡,self會自動傳遞,因此不需要傳遞它。每當根據Dog類創建實例時,都只需給最後兩個形參(name和age)提供值。

  屬性

  第4行處定義的兩個變量都有前綴self。以self為前綴的變量可供類中的所有方法使用,可以通過類的任何實例來訪問。self.name=name獲取與形參name相關聯的值,並將其賦給變量name,然後該變量被關聯到當前創建的實例。self.age=age的作用與此類似。
  像這樣可通過實例訪問的變量稱為 屬性

  Dog類還定義了另外兩個方法:sit()和roll_over()。這些方法執行時不需要額外的信息,因此它們只有一個形參self。

9.1.2 根據類創建實例

  創建一個表示特定小狗的實例:

my_dog = Dog('Willie', 6)
print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")

output:

My dog’s name is Willie.
My dog is 6 years old.

  第1行,讓Python創建一條名字為’Willie’,年齡為6的小狗。
  遇到這行代碼時,Python使用實參’Willie’和6 調用Dog類的方法__init__()。方法__init__()創建一個表示特定小狗的實例,並使用提供的值來設置屬性name和age。
  接下來,Python返回一個表示這條小狗的實例,而我們將這個實例賦給了變量my_dog。在這裡,命名約定很有用:通常可認為首字母大寫的名稱(如Dog)指的是類,而小寫的名稱(如my_dog)指的是根據類創建的實例。

  a. 訪問屬性——句點表示法

  要訪問實例的屬性,可使用句點表示法。
  句點表示法在Python中很常用,這種語法演示了Python如何獲悉屬性的值。在這裡,Python先找到實例my_dog,再查找與該實例相關聯的屬性name。
  在Dog類中引用這個屬性時,使用的是self.name和self.age。

  b. 調用方法

  根據Dog 類創建實例後, 就能使用句點表示法來調用Dog 類中定義的任何方法了。
  下面來讓小狗蹲下和打滾:

my_dog.sit()
my_dog.roll_over()

output:

Willie is now sitting.
Willie roll over!

  要調用方法,可指定實例的名稱(這裡是my_dog)和要調用的方法,並用句點分隔。
  遇到代碼my_dog.sit()時,Python在類Dog中查找方法sit()並運行其代碼。Python以同樣的方式解讀代碼my_dog.roll_over()。
  就像我們看到的輸出——Willie按我們的命令做了。

  c. 創建多個實例

my_dog = Dog('Willie', 6)
your_dog = Dog('Lucy', 3)
print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")
my_dog.sit()
print(f"\nYour dog's name is {your_dog.name}.")
print(f"Your dog is {your_dog.age} years old.")
your_dog.sit()

output:

My dog’s name is Willie.
My dog is 6 years old.
Willie is now sitting.

Your dog’s name is Lucy.
Your dog is 3 years old.
Lucy is now sitting.

  在本例中創建了兩條小狗,分別名為Willie和Lucy。每條小狗都是一個獨立的實例,有自己的一組屬性,能夠執行相同的操作。
  即使給第二條小狗指定同樣的名字和年齡,Python依然會根據Dog 類創建另一個實例。你可按需求根據一個類創建任意數量的實例,條件是將每個實例都存儲在不同的變量中,或者佔用列表或字典的不同位置。

Exercises

創建一個名為Restaurant的類,為其方法__init__()設置屬性restaurant_name和cuisine_type。
創建一個名為describe_restaurant() 的方法和一個名為open_restaurant()的方法,前者打印前述兩項信息,而後者打印一條消息,指出餐館正在營業。
根據這個類創建一個名為restaurant的實例,分別打印其兩個屬性,再調用前述兩個方法。