三、继承
在编写类时,并非总是要从头开始。如果要编写的类是一个既有的类的特殊版本,可使用继承 (inheritance)。当一个类继承另一个类时,将自动获得后者的所有属性和方法。原有的类称为父类 (parent class),而新类称为子类(child class)。子类不仅可以继承父类的所有属性和方法,还可以定义自己的属性和方法。
1、子类的__init__()方法
在既有的类的基础上编写新类,通常要调用父类的__init__()方法。这将初始化在父类的__init__()方法中定义的所有属性,从而让子类也可以使用这些属性。 下面在之前Car类的基础上创建新类电动汽车ElectricCar。
python
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odemeter=0
def getName(self):
long_name = f"{self.year} {self.make} {self.model}"
return long_name.title()
def read_odemeter(self):
print("Odemeter is", self.odemeter)
def update_odemeter(self,mileage):
self.odemeter += mileage
class ElectricCar(Car):
# 电动汽车
def __init__(self, make, model, year):
# 初始化父类的属性
super().__init__(make,model,year)
my_leaf=ElectricCar("Ford", "Mustang", 1999)
print(my_leaf.getName())
在创建子类时,父类必须包含在当前文件中,且位于子类前面。在定义子类时,必须在括号内指定父类的名称。super()是一个特殊的函数,让你能够调用父类的方法。父类也称为超类(superclass),函数名super由此得名。
2、给子类定义属性和方法
让一个类继承另一个类后,就可以添加区分子类和父类所需的新属性和新方法了。下面添加电动汽车独有的属性电池,以及描述该属性的方法。
python
class ElectricCar(Car):
# 电动汽车
def __init__(self, make, model, year):
# 初始化父类的属性
super().__init__(make,model,year)
self.battery = 100
def describe_battery(self):
print("The battery is", self.battery)
my_leaf=ElectricCar("Ford", "Mustang", 1999)
print(my_leaf.getName())
my_leaf.describe_battery()
3、重写父类中的方法
在使用子类模拟的实物的行为时,如果父类中的一些方法不能满足子类的需求,就可以用下面的方法重写:在子类中定义一个与要重写的父类方法同名的方法。这样,Python将忽略这个父类方法,只关注你在子类中定义的相应方法。
4、将实例用作属性
在使用代码模拟实物时,你可能会发现自己给类添加了太多细节:属性和方法越来越多,文件越来越长。在这种情况下,可能需要将类的一部分提取出来,作为一个独立的类。将大型类拆分成多个协同工作的小类,这种方法称为组合(composition)。
可以定义一个名为Battery的新类,它没有继承任何类。
python
class Battery:
def __init__(self, battery_size=100):
self.battery_size = battery_size
def describe_battery(self):
print("This car has a {} mileage.".format(self.battery_size))
创建一辆电动汽车,并将其赋给变量my_leaf。在描述电池时,需要使用电动汽车的属性battery:
python
class ElectricCar(Car):
# 电动汽车
def __init__(self, make, model, year):
# 初始化父类的属性
super().__init__(make,model,year)
self.battery = Battery()
my_leaf=ElectricCar("Ford", "Mustang", 1999)
print(my_leaf.getName())
my_leaf.battery.describe_battery()
输出结果和之前一样:

四、导入类
Python允许你将类存储在模块中,然后在主程序中导入所需的模块。
1、导入单个类
将Car类存储在一个名为car.py的模块中,该模块将覆盖前面的文件car.py。从现在开始,使用该模块的程序都必须使用更具体的文件名,如my_car.py。
python
from car import Car
my_new_car = Car('audi','a6',2024)
print(my_new_car.getName())
my_new_car.odometer = 200
my_new_car.read_odemeter()
import语句让Python打开模块car并导入其中的Car类。这样我们就可以使用Car类,就像它是在当前文件中定义的一样。
2、在一个模块中存储多个类
尽管同一个模块中的类之间应该存在某种相关性,但其实可以根据需要在一个模块中存储任意数量的类。
python
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odemeter=0
def getName(self):
long_name = f"{self.year} {self.make} {self.model}"
return long_name.title()
def read_odemeter(self):
print("Odemeter is", self.odemeter)
def update_odemeter(self,mileage):
self.odemeter += mileage
class Battery:
def __init__(self, battery_size=100):
self.battery_size = battery_size
def describe_battery(self):
print("This car has a {} mileage.".format(self.battery_size))
class ElectricCar(Car):
# 电动汽车
def __init__(self, make, model, year):
# 初始化父类的属性
super().__init__(make,model,year)
self.battery = Battery()
3、从一个模块中导入多个类
可以根据需要在程序文件中导入任意数量的类。如果要在同一个程序中创建燃油汽车和电动汽车,就需要将Car类和ElectricCar类都导入:
python
from car import Car,ElectricCar
my_mustang=Car('Ford','mustang',2000)
print(my_mustang.getName())
my_leaf=ElectricCar('tesla','leaf',2022)
print(my_leaf.getName())
当从一个模块中导入多个类时,用逗号分隔各个类。导入必要的类后,就可根据需要创建每个类的任意数量的实例了。

4、导入整个模块
还可以先导入整个模块,再使用点号访问需要的类。
python
import car
my_mustang=car.Car('Ford','mustang',2000)
print(my_mustang.getName())
my_leaf=car.ElectricCar('tesla','leaf',2022)
print(my_leaf.getName())
首先,导入整个car模块。接下来,使用语法module_name.classname访问需要的类。
5、导入模块中的所有类
要导入模块中的每个类,可使用下面的语法:
python
from module_name import *
6、在一个模块中导入另一个模块
有时候,需要将类分散到多个模块中,以免模块太大或者在同一个模块中存储不相关的类。在将类存储在多个模块中时,你可能会发现一个模块中的类依赖于另一个模块中的类。在这种情况下,可在前一个模块中导入必要的类。
五、Python标准库
Python标准库是一组模块,在安装Python时已经包含在内。你可以使用标准库中的任何函数和类,只需在程序开头添加一条简单的import语句即可。
在这个模块中,一个有趣的函数是randint()。它将两个整数作为参数,并随机返回一个位于这两个整数之间(含)的整数。
python
from random import randint
print(randint(1,6))
输出结果如下:
output
6