Python—类class复习
Python——类(class)复习
根据类来创建对象的方法被称为实例化
因此学会使用类(class)来进行编程就是初步进入面向对象编程的大门
1.1 创建和使用类
首先编写一个小狗的简单类Dog,它表示的不是特定的小狗,而是任何小狗。
在Dog类中将包含:小狗的名字和年龄;小狗的蹲下和打滚
编写完这个类之后,将使用它来创建表示特定小狗的实例
程序名称:dog.py
class Dog():
# 根据约定,在python中,首字母大写的名称指的是类,类定义中的括号Dog()是空的,因我要从空白创建这个类
"""一次模拟小狗的简单尝试"""
def __init__(self, name, age):
# 方法__init__():类中的函数称为方法,这个是一个特殊的方法,是一种约定,旨在避免Python默认方法与普通方法发生名称冲突
# 包括三个形参:self、name、age,形参self必不可少,而且必须位于其他形参前面
"""初始化属性name和age"""
# 以self为前缀的变量都可供类中的所有方法使用,还可以通过类的任何实例来访问这些变量。
# self.name = name获取存储在形参name中的值,并将其存储到变量name中,然后该变量被关联到当前创建的实例
self.name = name
self.age = age
def sit(self):
"""模拟小狗被命令时蹲下"""
print(self.name.title() + " is sitting")
def roll_over(self):
"""模拟小狗被命令时打滚"""
print(self.name.title() + " rolled over")
方法__init__()
:
**类中的函数被称为方法。**方法_init_()是一种特殊的方法,每当根据Dog类创建新实例时,Python都会自动运行它。
将方法__init__()
定义成了包含三个形参:self、name和age。其中形参self必不可少,还必须位于其它形参的前面。每当我们根据Dog类创建实例时,都只需给最 后两个形参(name和age)提供值。
以self
为前缀的变量都可供类中所有方法使用,我们还可以通过类的任何实例来访问这些变量。
self.name = name
获取存储在形参name中的值,并将其存储到变量name中,然后该变量被关联到当前创建的实例。
像name和age这样可以通过实例访问的变量被称为属性
同时,Dog类还定义了两个方法:sit()
和roll_over()
。由于这些方法不需要额外的信息,如名字或年龄,因此它们只有一个形参self。我们后面将创建的实例能够访问这些方法。
总结:
创建一个表示特定小狗的实例:
class Dog():
# 根据约定,在python中,首字母大写的名称指的是类
"""一次模拟小狗的简单尝试"""
def __init__(self, name, age):
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):
"""模拟小狗被命令时蹲下"""
print(self.name.title() + " is sitting")
def roll_over(self):
"""模拟小狗被命令时打滚"""
print(self.name.title() + " rolled over")
my_dog = Dog('while', 6)
print("My dog is", my_dog.name.title()+".")
代码my_dog = Dog('while', 6)
创建了一个名字为while,年龄为6的小狗。
遇到这行代码时,Python使用实参’willie’和6调用Dog类中的方法__init__()
。 方法__init__()
创建一个表示特定小狗的实例,并使用我们提供的值来设置属性name和age。我们将这个实例存储在变量my_dog中。
访问属性:要访问实例的属性,可使用句点表示法,即my_dog.name
调用方法:根据Dog类创建实例后,就可以使用句点表示法来调用Dog类中定义的任何方法。下面来让小狗蹲下和打滚
class Dog():
# 根据约定,在python中,首字母大写的名称指的是类
"""一次模拟小狗的简单尝试"""
def __init__(self, name, age):
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):
"""模拟小狗被命令时蹲下"""
print(self.name.title() + " is sitting")
def roll_over(self):
"""模拟小狗被命令时打滚"""
print(self.name.title() + " rolled over")
my_dog = Dog('while', 6)
print("My dog is", my_dog.name.title()+".")
#调用方法
my_dog.sit()
my_dog.roll_over()
创建多个实例:
可按需求根据类创建任意数量的实例。
class Dog():
# 根据约定,在python中,首字母大写的名称指的是类
"""一次模拟小狗的简单尝试"""
def __init__(self, name, age):
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):
"""模拟小狗被命令时蹲下"""
print(self.name.title() + " is sitting")
def roll_over(self):
"""模拟小狗被命令时打滚"""
print(self.name.title() + " rolled over")
my_dog = Dog('while', 6)
your_dog = Dog('lucy', 7)
print("My dog is", my_dog.name.title()+".")
print("Your dog is", your_dog.name.title()+".")
#调用方法
my_dog.sit()
my_dog.roll_over()
your_dog.sit()
your_dog.roll_over()
9.2 使用类和实例
类编写好后,大部分时间都将花在使用根据类创建的实例上。需要执行的一个重要任务是修改实例的属性。可以直接修改实例的属性, 也可以编写方法以特定的方式进行修改。
下面编写一个表示汽车的类,它存储了有关汽车的信息,还有一个汇总这些信息的方法:
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
def get_descript(self):
"""返回整洁的描述性信息"""
long_name = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()
# 创建实例
my_new_car = Car('Audi', 'A4', '2019')
# 调用方法
print(my_new_car.get_descript())
下面,我们添加一个随着时间变化的属性,用来存储汽车的总里程
类中每个属性都必须有初始值,哪怕这个值是0或空字符串。也就是代码中的:
self.make = make
self.model = model
self.year = year
下面来添加一个名为odometer_reading
的属性,其初始值总是为0。我们还添加了一个名为 read_odometer()
的方法,用于读取汽车的里程表:
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descript(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', '2019')
print(my_new_car.get_descript())
my_new_car.read_odometer()
下面来添加一个修改该属性的值的途径
可以以三种不同的方式修改属性的值:直接通过实例进行修改;通过方法进行设置;通过方法进行递增(增加特定的值)。下面依次介绍这些方法。
直接通过实例进行修改:
利用句点表示法
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descript(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', '2019')
print(my_new_car.get_descript())
my_new_car.odometer_reading = 23
my_new_car.read_odometer()
通过方法进行设置:
编写一个update_odometer()
的方法:
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descript(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', '2019')
print(my_new_car.get_descript())
my_new_car.update_odometer(500)
my_new_car.read_odometer()
可对方法update_odometer()
进行扩展,使其在修改里程表读数时做些额外的工作。下面来添加一些逻辑,禁止任何人将里程表读数往回调
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descript(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 odometer")
# 创建实例
my_new_car = Car('Audi', 'A4', '2019')
print(my_new_car.get_descript())
my_new_car.update_odometer(500)
my_new_car.read_odometer()
通过方法对属性的值进行递增 :
有时候需要将属性值递增特定的量,而不是将其设置为全新的值。
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descript(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 odometer")
def increment_odometer(self, miles):
"""将里程表读数增加指定量"""
self.odometer_reading += miles
# 创建实例
my_new_car = Car('Audi', 'A4', '2019')
print(my_new_car.get_descript())
my_new_car.update_odometer(500)
my_new_car.read_odometer()
my_new_car.increment_odometer(1000)
my_new_car.read_odometer()
9.3 继承
编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用继承。
一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类, 而新类称为子类。
子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法__init__()
需要父类施以援手。
例如,下面来模拟电动汽车。电动汽车是一种特殊的汽车,因此我们可以在前面创建的Car 类的基础上创建新类ElectricCar,这样我们就只需为电动汽车特有的属性和行为编写代码。
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descript(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 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', 2021)
print(my_tesla.get_descript())
创建子类时,父类必须包含在当前文件中,且位于子类前面。
在定义子类时,必须在括号内指定父类的名称。
并且在子类的方法__init__()
接受创建父类实例所需的信息
super()
是一个特殊函数,帮助Python将父类和子类关联起来。
这行代码让Python调用 ElectricCar的父类的方法__init__()
,让ElectricCar实例包含父类的所有属性。父类也称为超类(superclass),名称super因此而得名。
给子类定义属性和方法:
让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descript(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 odometer")
def increment_odometer(self, miles):
"""将里程表读数增加指定量"""
self.odometer_reading += miles
class ElectricCar(Car):
"""电动车的独到之处"""
def __init__(self, make, model, year):
"""初始化父类的属性,再初始化电动汽车特有的属性"""
super().__init__(make, model, year)
self.battery_size=70;
def describe_battery(self):
"""打印一条描述电瓶容量的消息"""
print("This car has " + str(self.battery_size) + "-kWh battery.")
my_tesla = ElectricCar('Tesla', 'model_s', 2021)
print(my_tesla.get_descript())
my_tesla.describe_battery()
重写父类的方法:
对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。
为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。
将实例用作属性:
可以将类的一部分作为一个独立的类提取出来。可以将大型类拆分成多个协同工作的小类。
例如:可将这些属性和方法提取出来,放到另一个名为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_descript(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 odometer")
def increment_odometer(self, miles):
"""将里程表读数增加指定量"""
self.odometer_reading += miles
class Battery():
"""
一次模拟电动车电瓶的简单尝试
定义了一个名为Battery的新类,它没有继承任何类。
"""
def __init__(self, battery_size=70):
"""初始化电瓶的属性"""
self.battery_size = battery_size
def describe_battery(self):
"""打印一条描述电瓶容量的消息"""
print("This car has " + str(self.battery_size) + "-kWh battery.")
class ElectricCar(Car):
"""电动车的独到之处"""
def __init__(self, make, model, year):
"""初始化父类的属性,再初始化电动汽车特有的属性"""
super().__init__(make, model, year)
# 在ElectricCar类中,添加了一个名为self.battery的属性
# 意义:这看似做了很多额外的工作,但现在我们想多详细地描述电瓶都可以,且不会导致ElectricCar类混乱不堪。
self.battery = Battery()
my_tesla = ElectricCar('Tesla', 'model_s', 2021)
print(my_tesla.get_descript())
my_tesla.battery.describe_battery()
9.4 导入类
模块化car.py,其中只包含Car类的代码:
文件:car.py
"""一个可用于表示汽车的类"""
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descript(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 odometer")
def increment_odometer(self, miles):
"""将里程表读数增加指定量"""
self.odometer_reading += miles
之后,创建另一个文件my_car.py,在其中导入car类并且创建其实例:
文件:my_car.py
from car import Car
my_car = Car('audi', 'a4', 2016)
print(my_car.get_descript())
my_car.odometer_reading = 23
my_car.read_odometer()
可根据需要在一个模块中存储任意数量的类。
文件:car.py
"""一个可用于表示燃油车和电动车的类"""
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descript(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 odometer")
def increment_odometer(self, miles):
"""将里程表读数增加指定量"""
self.odometer_reading += miles
class Battery():
"""一次模拟电动汽车电瓶的简单尝试"""
def __init__(self, battery_size=60):
"""初始化电瓶的属性"""
self.battery_size = battery_size
def describe_battery(self):
"""打印一条描述电瓶容量的消息"""
print("This car has a " + str(self.battery_size) + "-kWh battery.")
def get_range(self):
"""打印一条描述电瓶续航里程的消息"""
if self.battery_size == 70:
range = 240
elif self.battery_size == 85:
range = 270
else:
range = 200
message = "This car can go approximately " + str(range)
message += " miles on a full charge."
print(message)
class ElectricCar(Car):
"""模拟电动汽车的独特之处"""
def __init__(self, make, model, year):
"""
初始化父类的属性,再初始化电动汽车特有的属性
"""
super().__init__(make, model, year)
self.battery = Battery()
文件:my_electric_car.py
from car import ElectricCar
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descript())
my_tesla.battery.describe_battery()
my_tesla.battery.get_range()
最后,还可以进行在一个模块中导入多个类、导入整个模块、导入模块中的所有类等等操作