pathon筆記——第9章 類

1、創建和使用類
在 Python 中,通常可以認爲首字母大寫的名稱(如 Dog )指的是類,而小寫的名稱(如 my_dog )指的是根據類創建的實例。
(1)創建 Dog 類
例:
class Dog():
    #一次模擬小狗的簡單嘗試
    def __init__(self, name, age):
        #初始化屬性 name 和 age
        self.name = name
        self.age = age
    def sit(self):
        #模擬小狗被命令時蹲下
    print(self.name.title() + " is now sitting.")
    def roll_over(self):
    #模擬小狗被命令時打滾
        print(self.name.title() + " rolled over!")
說明: 方法 __init__()
  類中的函數稱爲 方法 ;你前面學到的有關函數的一切都適用於方法,就目前而言,唯一重要的差別是調用方法的方式。
  __init__() 是一個特殊的方法,每當你根據 Dog 類創建新實例時, Python 都會自動運行它。在這個方法的名稱中,開頭和末尾各有兩個下劃線,這是一種約定,旨在避免 Python 默認方法與普通方法發生名稱衝突。
  我們將方法 __init__() 定義成了包含三個形參: self 、 name 和 age 。在這個方法的定義中,形參 self 必不可少,還必須位於其他形參的前面。
  爲何必須在方法定義中包含形參 self 呢?
  因爲 Python 調用這個 __init__() 方法來創建 Dog 實例時,將自動傳入實參 self 。每個與類相關聯的方法調用都自動傳遞實參 self ,它是一個指向實例本身的引用,讓實例能夠訪問類中的屬性和方法。我們創建 Dog 實例時, Python 將調用 Dog 類的方法 __init__() 。我們將通過實參向 Dog() 傳遞名字和年齡; self 會自動傳遞,因此我們不需要傳遞它。每當我們根據 Dog 類創建實例時,都只需給最後兩個形參( name 和 age )提供值。
(2)根據類創建實例
例:
my_dog = Dog('willie', 6)
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
  1)訪問屬性
要訪問實例的屬性,可使用句點表示法。如:my_dog.name
  2)調用方法
例:
my_dog = Dog('willie', 6)
my_dog.sit()
my_dog.roll_over()
  3)創建多個實例
例:
my_dog = Dog('willie', 6)
your_dog = Dog('lucy', 3)
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
my_dog.sit()
print("\nYour dog's name is " + your_dog.name.title() + ".")
print("Your dog is " + str(your_dog.age) + " years old.")
your_dog.sit()

2、使用類和實例
(1)Car類
class Car():
    #一次模擬汽車的簡單嘗試
    def __init__(self, make, model, year):
        #初始化描述汽車的屬性
        self.make = make
        self.model = model
        self.year = year
    def get_descriptive_name(self):
        #返回整潔的描述性信息
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
(2)給屬性指定默認值
在有些情況下,如設置默認值時,在方法 __init__() 內指定這種初始值是可行的;如果你對某個屬性這樣做了,就無需包含爲它提供初始值的形參。
class Car():
    def __init__(self, make, model, year):
        #初始化描述汽車的屬性
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    def get_descriptive_name(self):
        #返回整潔的描述性信息
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        #打印一條指出汽車裏程的消息
        print("This car has " + str(self.odometer_reading) + " miles on it.")
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()
(3)修改屬性的值
可以以三種不同的方式修改屬性的值:直接通過實例進行修改;通過方法進行設置;通過方法進行遞增(增加特定的值)
   1)直接修改屬性的值
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 23
my_new_car.read_odometer()
   2)通過方法修改屬性的值
class Car():
    def __init__(self, make, model, year):
        #初始化描述汽車的屬性
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    def get_descriptive_name(self):
        #返回整潔的描述性信息
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        #打印一條指出汽車裏程的消息
        print("This car has " + str(self.odometer_reading) + " miles on it.")
    def update_odometer(self, mileage):
        #將里程錶讀數設置爲指定的值
        self.odometer_reading = mileage
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(23)
my_new_car.read_odometer()
   3)通過方法對屬性的值進行遞增
class Car():
    def __init__(self, make, model, year):
        #初始化描述汽車的屬性
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    def get_descriptive_name(self):
        #返回整潔的描述性信息
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        #打印一條指出汽車裏程的消息
        print("This car has " + str(self.odometer_reading) + " miles on it.")
    def update_odometer(self, mileage):
        #將里程錶讀數設置爲指定的值
        self.odometer_reading = mileage
    def increment_odometer(self, miles):
        #將里程錶讀數增加指定的量
        self.odometer_reading += miles
my_used_car = Car('subaru', 'outback', 2013)
print(my_used_car.get_descriptive_name())
my_used_car.update_odometer(23500)
my_used_car.read_odometer()
my_used_car.increment_odometer(100)
my_used_car.read_odometer()

3、繼承
    編寫類時,並非總是要從空白開始。如果你要編寫的類是另一個現成類的特殊版本,可使用 繼承 。一個類 繼承 另一個類時,它將自動獲得另一個類的所有屬性和方法;原有的類稱爲 父類 ,而新類稱爲 子類 。子類繼承了其父類的所有屬性和方法,同時還可以定義自己的屬性和方法。
(1)子類的方法 __init__()
例:
class Car():
    #一次模擬汽車的簡單嘗試
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    def get_descriptive_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        print("This car has " + str(self.odometer_reading) + " miles on it.")
    def update_odometer(self, mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
    def increment_odometer(self, miles):
        self.odometer_reading += miles
class ElectricCar(Car):
    #電動汽車的獨特之處
    def __init__(self, make, model, year):
        #初始化父類的屬性
        super().__init__(make, model, year)
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
說明:
1)創建子類時,父類必須包含在當前文件中,且位於子類前面。
2)定義子類時,必須在括號內指定父類的
3)名稱 super() 是一個特殊函數,幫助 Python 將父類和子類關聯起來。這行代碼讓 Python 調用 ElectricCar 的父類的方法 __init__() ,讓 ElectricCar 實例包含父類的所有屬性。父類也稱爲 超類 ( superclass ),名稱 super 因此而得名。
(2)給子類定義屬性和方法
class Car():
    #一次模擬汽車的簡單嘗試
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    def get_descriptive_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        print("This car has " + str(self.odometer_reading) + " miles on it.")
    def update_odometer(self, mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
    def increment_odometer(self, miles):
        self.odometer_reading += miles
class ElectricCar(Car):
    #Represent aspects of a car, specific to electric vehicles.
    def __init__(self, make, model, year):
        #電動汽車的獨特之處
        #初始化父類的屬性,再初始化電動汽車特有的屬性
        super().__init__(make, model, year)
        self.battery_size = 70
    def describe_battery(self):
        #打印一條描述電瓶容量的消息
        print("This car has a " + str(self.battery_size) + "-kWh battery.")
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
(3)重寫父類的方法
    對於父類的方法,只要它不符合子類模擬的實物的行爲,都可對其進行重寫。爲此,可在子類中定義一個這樣的方法,即它與要重寫的父類方法同名。這樣, Python 將不會考慮這個父類方法,而只關注你在子類中定義的相應方法。
例:假設 Car 類有一個名爲 fill_gas_tank() 的方法,它對全電動汽車來說毫無意義,因此你可能想重寫它。
class ElectricCar(Car):
--snip--
    def fill_gas_tank():
    #電動汽車沒有油箱
    print("This car doesn't need a gas tank!")
(4)將實例用作屬性
使用代碼模擬實物時,你可能會發現自己給類添加的細節越來越多:屬性和方法清單以及文件都越來越長。在這種情況下,可能需要將類的一部分作爲一個獨立的類提取出來。你可以將大型類拆分成多個協同工作的小類。
例:不斷給 ElectricCar 類添加細節時,我們可能會發現其中包含很多專門針對汽車電瓶的屬性和方法。在這種情況下,我們可將這些屬性和方法提取出來,放到另一個名爲 Battery 的類中,並將一個 Battery 實例用作 ElectricCar 類的一個屬性:
class Car():
    #一次模擬汽車的簡單嘗試
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    def get_descriptive_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        print("This car has " + str(self.odometer_reading) + " miles on it.")
    def update_odometer(self, mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
    def increment_odometer(self, miles):
        self.odometer_reading += miles
class Battery():
    #一次模擬電動汽車電瓶的簡單嘗試
    def __init__(self, battery_size=70):
        #初始化電瓶的屬性
        self.battery_size = battery_size
    def describe_battery(self):
        #打印一條描述電瓶容量的消息
        print("This car has a " + str(self.battery_size) + "-kWh battery.")
class ElectricCar(Car):
    #電動汽車的獨特之處
    def __init__(self, make, model, year):
        #初始化父類的屬性,再初始化電動汽車特有的屬性
        super().__init__(make, model, year)
        self.battery = Battery()
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()

4、導入類(與導入函數類似,此處略)
隨着你不斷地給類添加功能,文件可能變得很長,即便你妥善地使用了繼承亦如此。Python 允許你將類存儲在模塊中,然後在主程序中導入所需的模塊。
     在組織大型項目的代碼方面, Python 提供了很多選項。熟悉所有這些選項很重要,這樣你才能確定哪種項目組織方式是最佳的,並能理解別人開發的項目。一開始應讓代碼結構儘可能簡單。先儘可能在一個文件中完成所有的工作,確定一切都能正確運行後,再將類移到獨立的模塊中。如果你喜歡模塊和文件的交互方式,可在項目開始時就嘗試將類存儲到模塊中。先找出讓你能夠編寫出可行代碼的方式,再嘗試讓代碼更爲組織有序。

5、Python 標準庫
可使用標準庫中的任何函數和類,爲此只需在程序開頭包含一條簡單的 import 語句。
例:返回一個 1~6 內的整數
from random import randint
x = randint(1, 6)

6、類編碼風格
1)類名中的每個單詞的首字母都大寫,而不使用下劃線。實例名和模塊名都採用小寫格式,並在單詞之間加上下劃線。
2)對於每個類,都應緊跟在類定義後面包含一個文檔字符串。這種文檔字符串簡要地描述類的功能,並遵循編寫函數的文檔字符串時採用的格式約定。每個模塊也都應包含一個文檔字符串,對其中的類可用於做什麼進行描述。
3)可使用空行來組織代碼,但不要濫用。在類中,可使用一個空行來分隔方法;而在模塊中,可使用兩個空行來分隔類。
4)需要同時導入標準庫中的模塊和你編寫的模塊時,先編寫導入標準庫模塊的 import 語句,再添加一個空行,然後編寫導入你自己編寫的模塊的 import 語句。在包含多條 import 語句的程序中,這種做法讓人更容易明白程序使用的各個模塊都來自何方。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章