Advertisement

Python:从入门到实践-第九章(笔记)

阅读量:

9.1 : 创建和使用类

使用类几乎可以模拟任何东西


9.1.1 : 创建Dog类

每当根据Dog类创建一个实例时,该实例将被记录其叫名及年龄信息,并被赋予蹲下和打滚的能力.

复制代码
 # 定义一个名为Dog的类

    
 class Dog:
    
     """一次模拟小狗的简单尝试"""
    
  
    
     # 类中的函数称为方法:方法__init__();
    
     # 方法__init__()定义成包含三个形参:self、name、和age;
    
     # 形参self必不可少,必须位于其他形参的前面;
    
     # 通过实参向Dog()传递名字和年龄,self会自动传递
    
     def __init__(self, name, age):
    
     """初始化属性name和age"""
    
  
    
     # 获取与行参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} rolled over!")

9.1.2 :根据类创建实例

其可被视为关于创建实例的定义。Dog类是一系列定义告诉Python生成表示特定小狗的对象。

复制代码
 # 定义一个名为Dog的类

    
 class Dog:
    
     """一次模拟小狗的简单尝试"""
    
  
    
     # 类中的函数称为方法:方法__init__();
    
     # 方法__init__()定义成包含三个形参:self、name、和age;
    
     # 形参self必不可少,必须位于其他形参的前面;
    
     # 通过实参向Dog()传递名字和年龄,self会自动传递
    
     def __init__(self, name, age):
    
     """初始化属性name和age"""
    
  
    
     # 获取与行参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} rolled over!")
    
  
    
  
    
 # 让python创建一条名字为'Willie'、年龄为6的小狗。
    
 my_dog = Dog('Willie', 6)
    
 your_dog = Dog('Lucy', 3)
    
 my_dog.sit()
    
 my_dog.roll_over()
    
  
    
 # 编写了如下代码来访问my_dog的属性name和age的值;
    
 print(f"\nMy 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()

运行结果:

现在威利正在坐着。
威利翻了个身。
我家宠物的名字叫威利。
我的宠物已经陪伴我六岁了。
现在威利正在坐着。
我的朋友家有一条宠物的名字叫露西。
我的伴侣已经陪伴我三年了。
露西现在 lying down.


9.2:使用类和实例

该技术可用于模仿现实世界中的多种场景。一个类不仅具有能力去复制实例的各种属性,并且能够通过定义一系列操作来实现特定的更改。


9.2.1:Car 类

创建一个能够存储与汽车相关的信息,并且包含汇总这些信息的方法。

复制代码
 class Car:

    
     """一次模拟汽车的简单尝试"""
    
     
    
 # 定义方法,该方法还包含另外三个形参:make、model和year
    
  
    
     def __init__(self, make, model, year):
    
     """初始化描述汽车的属性"""
    
     self.make = make
    
     self.model = model
    
     self.year = year
    
  
    
 # 定义一个名为get_descriptive_name的方法,它使用属于year、make和model创建一个对汽车进行描述的字符串;
    
  
    
     def get_descriptive_name(self):
    
     """返回整洁的描述性信息"""
    
     long_name = f"{self.year} {self.make} {self.model}"
    
     return long_name.title()
    
  
    
  
    
 # 根据Car类创建一个实例,并将其赋给变量my_new_car;
    
  
    
 my_new_car = Car('audi', 'a4', 2019)
    
 print(my_new_car.get_descriptive_name())

9.2.2 :给属性指定默认值

当创建实例时,在构造函数中为这些属性设置默认值,并不需要在参数列表中显式声明它们。

复制代码
 class Car:

    
  
    
     def __init__(self, make, model, year):
    
     """初始化描述汽车的属性"""
    
     self.make = make
    
     self.model = model
    
     self.year = year
    
  
    
     # 添加一个名为odmeter_reading的属性,其初始值总是为0
    
     self.odometer_reading = 0
    
  
    
  
    
     def get_descriptive_name(self):
    
     """返回整洁的描述性信息"""
    
     long_name = f"{self.year}  {self.make}  {self.model}"
    
     return long_name.title()
    
  
    
     # 定义一个名为read_odometer的方法
    
     def read_odometer(self):
    
     """打印一条指出汽车里程的消息"""
    
     print(f"This car has {self.odometer_reading} miles on it.")
    
  
    
  
    
 my_new_car = Car('audi', 'a4', '2019')
    
 print(my_new_car.get_descriptive_name())
    
 my_new_car.read_odometer()

9.2.3 :修改属性的值

以三种方式修改属性的值:

  • 基于实例的调整
  • 采用方式设置参数
  • 并利用递增操作设定指定增量值

a. 直接修改属性的值

复制代码
 class Car:

    
  
    
     def __init__(self, make, model, year):
    
     """初始化描述汽车的属性"""
    
     self.make = make
    
     self.model = model
    
     self.year = year
    
  
    
     # 添加一个名为odometer_reading的属性,其初始值总是为0
    
     self.odometer_reading = 0
    
  
    
  
    
     def get_descriptive_name(self):
    
     """返回整洁的描述性信息"""
    
     long_name = f"{self.year}  {self.make}  {self.model}"
    
     return long_name.title()
    
  
    
     # 定义一个名为read_odometer的方法
    
     def read_odometer(self):
    
     """打印一条指出汽车里程的消息"""
    
     print(f"This car has {self.odometer_reading} miles on it.")
    
  
    
  
    
 my_new_car = Car('audi', 'a4', '2019')
    
 print(my_new_car.get_descriptive_name())
    
  
    
 # 使用句点表示法直接访问并设置汽车的属性odometer_reading.
    
 my_new_car.odometer_reading = 23
    
 my_new_car.read_odometer()

b. 通过方法修改属性的值

复制代码
 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 = f"{self.year} {self.make} {self.model}"
    
     return long_name.title()
    
  
    
     def read_odometer(self):
    
     """打印一条指出汽车里程的消息"""
    
     print(f"This car has {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!")
    
  
    
  
    
 my_new_car = Car('audi', 'a4', 2019)
    
 print(my_new_car.get_descriptive_name())
    
  
    
 my_new_car.update_odometer(23)
    
 my_new_car.read_odometer()

c. 通过方法对属性的值进行递增

复制代码
 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 = f"{self.year} {self.make} {self.model}"
    
     return long_name.title()
    
  
    
     def read_odometer(self):
    
     """打印一条指出汽车里程的消息"""
    
     print(f"This car has {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!")
    
  
    
     # 新增方法,接受一个单位为英里的数,并将其加入self.odometer_reading中;
    
     def increment_odometer(self, miles):
    
     """将里程表读数增加指定的量"""
    
     self.odometer_reading += miles
    
  
    
  
    
 my_used_car = Car('subaru', 'outback', 2015)
    
 print(my_used_car.get_descriptive_name())
    
  
    
 my_used_car.update_odometer(23_500)
    
 my_used_car.read_odometer()
    
  
    
 my_used_car.increment_odometer(100)
    
 my_used_car.read_odometer()

9.3:继承

编写一个新代码块时,并非总是要从头开始。当一个新定义的代码块继承已存在的代码块时(即其语法结构或数据类型与其原有代码块相同),该系统会自动获取原有代码块的所有属性与方法(即其成员变量与函数)。原有被继承的那个则被称为父类别(parent class),而新定义的那个则被称为子类别(subclass)。原有的那个称为父类别(parent class);而新定义的那个则被称为子类别(subclass)。


9.3.1 : 子类的方法__init__()

在既有类的基础上编写新类时,通常要调用父类的方法 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 = f"{self.year} {self.make} {self.model}"
    
     return long_name.title()
    
  
    
     def read_odometer(self):
    
     print(f"This car has {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
    
  
    
  
    
 # 定义了子类ElectricCar,定义子类时,必须在圆括号内指定父类的名称;
    
 class ElectricCar(Car):
    
     """电动汽车的独特之处"""
    
     # 方法 init 接受创建Car实例所需的信息
    
     def __init__(self, make, model, year):
    
     """初始化父类的属性"""
    
     # super()是一个特殊函数,让你能够调用父类的方法。
    
     super().__init__(make, model, year)
    
  
    
  
    
 # 创建ElectricCar类的一个实例,并将其赋给变量my_tesla.
    
 my_tesla = ElectricCar('tesla', 'model s', 2019)
    
 print(my_tesla.get_descriptive_name())

9.3.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 = f"{self.year} {self.make} {self.model}"
    
     return long_name.title()
    
  
    
     def read_odometer(self):
    
     print(f"This car has {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
    
  
    
  
    
 # 定义了子类ElectricCar,定义子类时,必须在圆括号内指定父类的名称;
    
 class ElectricCar(Car):
    
     """电动汽车的独特之处"""
    
     # 方法 init 接受创建Car实例所需的信息
    
     def __init__(self, make, model, year):
    
     """
    
     初始化父类的属性
    
     再初始化电动汽车特有的属性
    
     """
    
     # super()是一个特殊函数,让你能够调用父类的方法。
    
     super().__init__(make, model, year)
    
     # 添加新属性self.battery_size, 并设置其初始值75
    
     self.battery_size = 75
    
  
    
     # 添加了一个名为describe_battery()的方法,打印有关电瓶的信息;
    
     def describe_battery(self):
    
     """打印一条描述电瓶容量的消息"""
    
     print(f"This car has a {self.battery_size}-KWh battery. ")
    
  
    
  
    
 # 创建ElectricCar类的一个实例,并将其赋给变量my_tesla.
    
 my_tesla = ElectricCar('tesla', 'model s', 2019)
    
 print(my_tesla.get_descriptive_name())
    
 my_tesla.describe_battery()

9.3.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 = f"{self.year} {self.make} {self.model}"
    
     return long_name.title()
    
  
    
     def read_odometer(self):
    
     print(f"This car has {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
    
  
    
  
    
 # 定义了子类ElectricCar,定义子类时,必须在圆括号内指定父类的名称;
    
 class ElectricCar(Car):
    
     """电动汽车的独特之处"""
    
  
    
     # 方法 init 接受创建Car实例所需的信息
    
     def __init__(self, make, model, year):
    
     """
    
     初始化父类的属性
    
     再初始化电动汽车特有的属性
    
     """
    
     # super()是一个特殊函数,让你能够调用父类的方法。
    
     super().__init__(make, model, year)
    
     # 添加新属性self.battery_size, 并设置其初始值75
    
     self.battery_size = 75
    
  
    
     # 添加了一个名为describe_battery()的方法,打印有关电瓶的信息;
    
     def describe_battery(self):
    
     """打印一条描述电瓶容量的消息"""
    
     print(f"This car has a {self.battery_size}-KWh battery. ")
    
  
    
     def fill_gas_tank(self):
    
     """电动汽车没有油箱"""
    
     print("This car doesn't need a gas tank!")
    
  
    
  
    
 # 创建ElectricCar类的一个实例,并将其赋给变量my_tesla.
    
 my_tesla = ElectricCar('tesla', 'model s', 2019)
    
 print(my_tesla.get_descriptive_name())
    
 my_tesla.describe_battery()
    
 my_tesla.fill_gas_tank()

9.3.4 :将实例用作属性

首先从一个现有的类中分离出一部分代码,并将其单独成为一个新的子类;然后对于大型类来说,我们将其分解为若干个相互协作的小模块。

复制代码
 # 创建子类时候,父类必须在子类前;

    
 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 = f"{self.year} {self.make} {self.model}"
    
     return long_name.title()
    
  
    
     def read_odometer(self):
    
     print(f"This car has {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=75):
    
     """初始化电瓶的属性"""
    
     self.battery_size = battery_size
    
  
    
     def describe_battery(self):
    
     """打印一条描述电瓶容量的消息"""
    
     print(f"This car has a {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', 2019)
    
  
    
 print(my_tesla.get_descriptive_name())
    
 my_tesla.battery.describe_battery()

给Battery类添加一个方法,它根据电瓶容量报告汽车的续航里程:

复制代码
 # 创建子类时候,父类必须在子类前;

    
 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 = f"{self.year} {self.make} {self.model}"
    
     return long_name.title()
    
  
    
     def read_odometer(self):
    
     print(f"This car has {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=75):
    
     """初始化电瓶的属性"""
    
     self.battery_size = battery_size
    
  
    
     def describe_battery(self):
    
     """打印一条描述电瓶容量的消息"""
    
     print(f"This car has a {self.battery_size}-KWh battery.")
    
  
    
     def get_range(self):
    
     """打印一条消息,指出电瓶的续航里程"""
    
     if self.battery_size == 75:
    
         range = 260
    
     elif self.battery_size == 100:
    
         range = 315
    
  
    
     print(f"This car can go about {range} miles on a full charge.")
    
  
    
  
    
 class ElectricCar(Car):
    
     """电动汽车的独特之处"""
    
  
    
     def __init__(self, make, model, year):
    
     """
    
     初始化父类属性
    
     再初始化电动汽车特有的属性
    
     """
    
     super().__init__(make, model, year)
    
     self.battery = Battery()
    
  
    
  
    
 my_tesla = ElectricCar('tesla', 'model s', 2019)
    
 print(my_tesla.get_descriptive_name())
    
 my_tesla.battery.describe_battery()
    
 my_tesla.battery.get_range()

9.4 :导入类

每当为类添加功能时(even when adding functionalities to a class),文件可能会变得非常长),即便合理地利用了继承机制(even with proper use of inheritance)也是如此(it still may become lengthy)。因此(therefore),为了使文件尽可能简洁明了(to keep the file as concise and clear as possible),建议将类存储在模块中(store the class in a module),然后在主程序中导入所需模块(and then import the required modules in the main program)。


9.4.1:导入单个类

复制代码
 # 让Python 打开模块car并导入其中的Car类

    
 from car import Car
    
  
    
 my_new_car = Car('audi', 'a4', 2019)
    
 print(my_new_car.get_descriptive_name())
    
  
    
 my_new_car.odometer_reading = 23
    
 my_new_car.read_odometer()

9.4.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 = f"{self.year} {self.make} {self.model}"
    
     return long_name.title()
    
  
    
     def read_odometer(self):
    
     print(f"This car has {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=75):
    
     """初始化电瓶的属性"""
    
     self.battery_size = battery_size
    
  
    
     def describe_battery(self):
    
     """打印一条描述电瓶容量的消息"""
    
     print(f"This car has a {self.battery_size}-KWh battery.")
    
  
    
     def get_range(self):
    
     """打印一条消息,指出电瓶的续航里程"""
    
     if self.battery_size == 75:
    
         range = 260
    
     elif self.battery_size == 100:
    
         range = 315
    
  
    
     print(f"This car can go about {range} miles on a full charge.")
    
  
    
  
    
 class ElectricCar(Car):
    
     """电动汽车的独特之处"""
    
  
    
     def __init__(self, make, model, year):
    
     """
    
     初始化父类属性
    
     再初始化电动汽车特有的属性
    
     """
    
     super().__init__(make, model, year)
    
     self.battery = Battery()

导入ElectricCar类

复制代码
 from car import ElectricCar

    
 my_tesla = ElectricCar('tesla', 'model s', 2019)
    
  
    
 print(my_tesla.get_descriptive_name())
    
 my_tesla.battery.describe_battery()
    
 my_tesla.battery.get_range()

9.4.3 : 从一个模块中导入多个类

复制代码
 from car import Car, ElectricCar

    
 my_beetle = Car('volkswagen', 'beetle', 2019)
    
 print(my_beetle.get_descriptive_name())
    
  
    
 my_beetle = ElectricCar('tesla', 'roadster', 2019)
    
 print(my_beetle.get_descriptive_name())

9.4.5 : 导入整个模块

复制代码
 import car

    
  
    
 my_beetle = car.Car('volkswagen', 'beetle', 2019)
    
 print(my_beetle.get_descriptive_name())
    
  
    
 my_beetle = car.ElectricCar('tesla', 'roadster', 2019)
    
 print(my_beetle.get_descriptive_name())

9.4.5 :导入模块中的所有类

复制代码
    from module_name import *

不推荐使用这种导入方式:

  • 没有明确地指出使用了模块中的哪些类
  • 引发名称方面的迷惑

9.46 :在一个模块中导入另一个模块

复制代码
 from car import Car

    
 from electric_car import ElectricCar
    
  
    
 my_beetle = Car('volkswagen', 'beetle', 2019)
    
 print(my_beetle.get_descriptive_name())
    
  
    
 my_tesla = ElectricCar('tesla', 'roadster', 2019)
    
 print(my_tesla.get_descriptive_name())

9.4.7 : 使用别名

导入类时,也可为指定别名:

比如:

复制代码
 from electric_car import ElectricCar as EC

    
 my_tesla = EC('tesla', 'roadster', 2019)

9.5 : Python标准库

Python标准库是一组模块,我们安装的Python都包含它。

该函数 randont() 接受两个整数作为输入参数,并在其间生成一个随机的整数值。

例如:生成一个位于1和6之间的随机整数:

复制代码
 from random import randint

    
 print(randint(1, 6))

在模块random中,另一个有实用价值的函数是choice()。该函数接受一个列表或元组作为输入,并从其中随机选取一个元素进行返回。

复制代码
 from random import choice

    
 players = ['charles', 'martina', 'michael', 'florence', 'eli']
    
 first_up = choice(players)
    
 print(first_up)

全部评论 (0)

还没有任何评论哟~