知識(shí)點(diǎn)
- 類的名字要首字母大寫。
- 類由屬性和方法組成。
- 類里的函數(shù)稱為方法。
- 可以用一個(gè)類創(chuàng)造多個(gè)實(shí)例,只要實(shí)例名不同即可。
- 類里面的所有方法都需要self參數(shù)。
- 子類可以在super().init()語句的括號(hào)中添加新的參數(shù),使子類不僅僅是繼承父類的所有參數(shù)。
- 一個(gè)模塊中可以存儲(chǔ)多個(gè)類。
1. 創(chuàng)建一個(gè)類
class Dog():
#創(chuàng)建一個(gè)Dog類,注意首字母大寫和冒號(hào)
"""A simple attempt to model a dog.""" #docstring
def __init__(self, name, age):
"""Initialize name and age attributes.""" #docstring
self.name = name
self.age = age
def sit(self):
"""Simulate a dog sitting in response to a command."""
print(self.name.title() + " is now sitting.")
def roll_over(self):
"""Simulate rolling over in response to a command."""
print(self.name.title() + " rolled over!")
注意:
- 類名要首字母大寫
- 類名后面的括號(hào)里面為空,表示這是從零開始創(chuàng)建的類,沒有繼承其他類
-
--init--()方法較為特殊,用類創(chuàng)建實(shí)例時(shí),自動(dòng)調(diào)用--init--()方法,其他方法則需要輸入代碼調(diào)用 - 類中的方法必須要有一個(gè)
self參數(shù),且要將self參數(shù)放在最前面 -
--init--()方法下面定義的變量都要有self前綴,這樣可以被類中所有的方法調(diào)用 - 可以通過實(shí)例查看的變量稱為屬性
2. 創(chuàng)建一個(gè)實(shí)例
格式: 實(shí)例名=類名(參數(shù))
輸入:
class Dog():
---snip--- #Dog類具體細(xì)節(jié)見上,這=這里省略
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.") #數(shù)字要轉(zhuǎn)為字符
my_dog.sit()
輸出:
My dog's name is Willie.
My dog is 6 years old.
Willie is now sitting.
(1) 獲取屬性
格式:instance_name.attribute_name
上例中,生成實(shí)例時(shí),括號(hào)中的‘Willie’一開始還只是一個(gè)字符串,被作為實(shí)參傳送給類中name形參后,被self.name = name語句轉(zhuǎn)換為類的屬性,并使用my_dog.name來獲取屬性的值。
(2)調(diào)用方法
格式:instance_name.method_name
上例中,當(dāng)Python讀到my_dog.sit(),Python為轉(zhuǎn)向Dog類,執(zhí)行里面的sit()方法。
3. 使用類和實(shí)例
輸入:
class Car():
"""A simple attempt to represent a car."""
def __init__(self, manufacturer, model, year):
"""Initialize attributes to describe a car."""
self.manufacturer = manufacturer
self.model = model
self.year = year
def get_descriptive_name(self):
"""Return a neatly formatted descriptive name."""
long_name = str(self.year) + ' ' + self.manufacturer + ' ' + self.model
return long_name.title()
my_new_car=Car('audi','a4',2016)
print(my_new_car.get_descriptive_name())
輸出:
2016 Audi A4
(1) 給屬性設(shè)置默認(rèn)值
在上例的基礎(chǔ)上,添加odometer_reading屬性和read_odometer方法,并將odometer_reading屬性默認(rèn)值設(shè)為0。
輸入:
class Car():
"""A simple attempt to represent a car."""
def __init__(self, manufacturer, model, year):
"""Initialize attributes to describe a car."""
self.manufacturer = manufacturer
self.model = model
self.year = year
self.odometer_reading = 0 #odometer_reading默認(rèn)值設(shè)為0
def get_descriptive_name(self):
"""Return a neatly formatted descriptive name."""
long_name = str(self.year) + ' ' + self.manufacturer + ' ' + self.model
return long_name.title()
def read_odometer(self):
"""Print a statement showing the car's mileage."""
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()
輸出:
2016 Audi A4
This car has 0 miles on it.
(2) 更改默認(rèn)值
1.直接法:
格式: instance_name.attribute_name = new_value
輸入:
class Car():
---snip---
my_new_car=Car('audi','a4',2016)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 23 #更改默認(rèn)值
my_new_car.read_odometer()
輸出:
2016 Audi A4
This car has 23 miles on it.
2.通過方法更改屬性的值
輸入:
class Car():
---snip---
def update_odometer(self, mileage):
"""
Set the odometer reading to the given value.
Reject the change if it attempts to roll the odometer back.
"""
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")
my_new_car=Car('audi','a4',2016)
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(300)
my_new_car.read_odometer()
通過類里的update_odometer方法改變屬性的值。需要傳參。
輸出:
2016 Audi A4
This car has 300 miles on it.
4. 繼承
類不一定從零開始創(chuàng)建,一個(gè)新類可以從另外一個(gè)類中繼承所有的屬性和方法,并且還可以為自己添加新的類和方法。
格式:class child_class (parent_class)
child_class為子類,parent_class為父類。
(1) 利用繼承創(chuàng)建一個(gè)新類
輸入:
class Car():
---snip---
class ElectricCar(Car):
"""Models aspects of a car, specific to electric vehicles."""
def __init__(self, manufacturer, model, year):
"""
Initialize attributes of the parent class.
Then initialize attributes specific to an electric car.
"""
super().__init__(manufacturer, model, year)
my_tesla = ElectricCar('tesla', 'roadster', 2015)
print(my_tesla.get_descriptive_name())
輸出:
2015 Tesla Roadster
注意:
-
__init__方法接收創(chuàng)建一個(gè)Car類所需的所有參數(shù),并且初始化Car類。 - 初始化Car類后,
super()函數(shù)建立父類與子類的連接,讓ElectricCar類繼承Car類中所有的方法和屬性,super().init(...)語句的括號(hào)中,可以添加子類需要的新參數(shù)。
(2) 為子類添加屬性和方法
可以直接在super().__init__(...)語句下面添加子類獨(dú)有的屬性。
輸入:
class Car():
---snip---
class ElectricCar(Car):
"""Models aspects of a car, specific to electric vehicles."""
def __init__(self, manufacturer, model, year):
"""
Initialize attributes of the parent class.
Then initialize attributes specific to an electric car.
"""
super().__init__(manufacturer, model, year)
self.battery_size = 70 #添加新屬性,并且設(shè)置默認(rèn)值
def describe_battery(self): #添加新方法
"""Print a statement describing the battery size."""
print("This car has a " + str(self.battery_size) + "-kWh battery.")
my_tesla = ElectricCar('tesla', 'roadster', 2015)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
輸出:
2015 Tesla Roadster
This car has a 70-kWh battery.
(3) 重寫父類方法
子類會(huì)繼承父類所有的方法和屬性,當(dāng)某個(gè)繼承來的方法需要更改時(shí),我們只需要用和原來方法相同的方法名,重新定義方法。
例如,電動(dòng)車沒有油箱,所以我們要把ElectricCar類中的fill_gas_tank方法更改一下。
輸入:
class ElectricCar(Car)
---snip---
def fill_gas_tank():
"""electric cars don't have gas tanks"""
print("This car doesn't need a gas tank!")
這樣,新的fill_gas_tank方法會(huì)覆蓋從Car中繼承的fill_gas_tank方法。
(4) 將實(shí)例作為屬性
當(dāng)屬性和方法較多時(shí),可以將一部分屬性和方法分離出來,作為單獨(dú)的類。
輸入:
class Car():
---snip---
class Battery():
"""A simple attempt to model a battery for an electric car."""
def __init__(self, battery_size=60):
"""Initialize the batteery's attributes."""
self.battery_size = battery_size
def describe_battery(self):
"""Print a statement describing the battery size."""
print("This car has a " + str(self.battery_size) + "-kWh battery.")
class ElectricCar(Car):
"""Models aspects of a car, specific to electric vehicles."""
def __init__(self, manufacturer, model, year,battery_size):
"""
Initialize attributes of the parent class.
Then initialize attributes specific to an electric car.
"""
super().__init__(manufacturer, model, year)
self.battery = Battery(battery_size)
my_tesla = ElectricCar('tesla', 'roadster', 2015,70)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
輸出:
2015 Tesla Roadster
This car has a 70-kWh battery.
上例將與電池相關(guān)的屬性和方法分離出來,作為一個(gè)新類。通過將類Battery的實(shí)例作為類ElectricCar的battery屬性,將兩個(gè)類關(guān)聯(lián)起來,雖然類Battery中的參數(shù)battery_size默認(rèn)值為60,卻可以由實(shí)例my_tesla的實(shí)參改為70。
5. 導(dǎo)入類
和函數(shù)相同,當(dāng)程序非常復(fù)雜時(shí),我們可以將類單獨(dú)保存為一個(gè)模塊,在主程序的開頭導(dǎo)入模塊即可。
(1)單獨(dú)導(dǎo)入一個(gè)類
導(dǎo)入格式:
from module_name import Class_name
使用格式:
instance_name = Class(arguments)
instance_name.attribute
instance_name.method(arguments)
(2)導(dǎo)入多個(gè)類
導(dǎo)入格式:
from module_name import Class1_name,Class2_name,...,Classn_name
使用格式:
instance_name = Class(arguments)
instance_name.attribute
instance_name.method(arguments)
(3)導(dǎo)入整個(gè)模塊
導(dǎo)入格式:
import module_name
使用格式:
instance_name =module_name.Class(arguments)
instance_name.attribute
instance_name.method(arguments)
只是在用導(dǎo)入的類生成實(shí)例時(shí),需要加上module_name,其他時(shí)候不需要。
(4)導(dǎo)入模塊中所有類(不推薦)
導(dǎo)入格式:
from module_name import *
不推薦這種方法,會(huì)弄不清到底使用了哪些類,并且可能造成模塊中的類名與主程序的類名沖突。
(5)在一個(gè)模塊中導(dǎo)入另一個(gè)模塊
需要用到繼承時(shí)使用,與主程序?qū)肽K的格式相同
推薦格式:
from module_name import Class_name
6. 類編程風(fēng)格
- 類名應(yīng)該采用駝峰命名法,即不使用下劃線,每個(gè)單詞首字母大寫
- 實(shí)例名和模塊名需要小寫,單詞間用下劃線隔開
- 每個(gè)類定義的下面都應(yīng)該緊跟一個(gè)docstring,類的每個(gè)方法下面也應(yīng)該有docsting來描述其功能