python编程:从入门到实践 (第一版) 第九章学习笔记

第9章:类

9.1 创建和使用类
9.1.1 创建dog类

根据Dog 类创建的每个实例都将存储名字和年龄。我们赋予了每条小狗蹲下(sit()) 和打滚(roll_over()) 的能力:

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!")
9.1.2 根据类创建实例

可将类视为有关如何创建实例的说明

class Dog():
--snip--
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.")
访问属性

要访问实例的属性,可使用句点表示法。我们编写了如下代码来访问my_dog 的属性name 的值:

my_dog.name
调用方法

根据Dog 类创建实例后,就可以使用句点表示法来调用Dog 类中定义的任何方法。下面来让小狗蹲下和打滚:

class Dog():
--snip--
my_dog = Dog('willie', 6)
my_dog.sit()
my_dog.roll_over()
创建多个实例
class Dog():
--snip--
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()
9.2 使用类和实例

你可以使用类来模拟现实世界中的很多情景。类编写好后,你的大部分时间都将花在使用根据类创建的实例上。你需要执行的一个重要任务是修改实例的属性。你可以直接修改实例的属性,也可以编写方法以特定的方式进行修改。

9.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())

输出:

2016 Audi A4
9.2.2 给属性指定默认值

类中的每个属性都必须有初始值,哪怕这个值是0或空字符串。在有些情况下,如设置默认值时,在方法__init__() 内指定这种初始值是可行的;如果你对某个属性这样做了,就无需包含为它提供初始值的形参。
下面来添加一个名为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_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()
9.2.3 修改属性的值

可以以三种不同的方式修改属性的值:直接通过实例进行修改;通过方法进行设置;通过方法进行递增(增加特定的值)。下面依次介绍这些方法:

直接修改属性的值

要修改属性的值,最简单的方式是通过实例直接访问它。下面的代码直接将里程表读数设置为23:

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.odometer_reading = 23
my_new_car.read_odometer()
通过方法修改属性的值

如果有替你更新属性的方法,将大有裨益。这样,你就无需直接访问属性,而可将值传递给一个方法,由它在内部进行更新。

class Car():
    def __init__(self, make, model, year):
        --snip--

    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()

方法update_odometer() 接受一个里程值,并将其存储到self.odometer_reading 中。
可对方法update_odometer() 进行扩展,使其在修改里程表读数时做些额外的工作。下面来添加一些逻辑,禁止任何人将里程表读数往回调:

class Car():
    def __init__(self, make, model, year):
        --snip--

    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', 2016)
print(my_new_car.get_descriptive_name)
my_new_car.update_odometer(23)
my_new_car.read_odometer()

现在,update_odometer() 在修改属性前检查指定的读数是否合理。如果新指定的里程(mileage )大于或等于原来的里程(self.odometer_reading ),就将里程表读数改为新指定的里程;否则就发出警告,指出不能将里程表往回拨

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

有时候需要将属性值递增特定的量,而不是将其设置为全新的值。假设我们购买了一辆二手车,且从购买到登记期间增加了100英里的里程,下面的方法让我们能够传递这个增量,并相应地增加里程表读数:

class Car():
    --snip--
    def update_odometer(self, mileage):
        --snip--
    
    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()
9.3 继承

编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用继承 。一个类继承 另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类 ,而新类称为子类 。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

9.3.1 子类的方法__init__()

创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法__init__() 需要父类施以援手。

例如,下面来模拟电动汽车。电动汽车是一种特殊的汽车,因此我们可以在前面创建的Car 类的基础上创建新类ElectricCar ,这样我们就只需为电动汽车特有的属性和行为编写代码。

electric_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_descriptive_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name

    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())

创建子类时,父类必须包含在当前文件中,且位于子类前面。定义子类时,必须在括号内指定父类的名称。

super() 是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用ElectricCar 的父类的方法__init__() ,让ElectricCar 实例包含父类的所有属性。父类也称为超类 (superclass),名称super因此而得名。

9.3.3 给子类定义属性和方法

让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。

下面来添加一个电动汽车特有的属性(电瓶),以及一个描述该属性的方法。我们将存储电瓶容量,并编写一个打印电瓶描述的方法:

class Car():
    --snip--

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 a " + str(self.battery_size) + "-KWh battery.")

my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
9.3.4 重写父类的方法

对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。

假设Car 类有一个名为fill_gas_tank() 的方法,它对全电动汽车来说毫无意义,因此你可能想重写它。下面演示了一种重写方式:

def ElectricCar(Car):
	--snip--
	def fill_gas_tank():
		"""电动汽车没有油箱"""
		print("This car doesn't need a gas tank.")

现在,如果有人对电动汽车调用方法fill_gas_tank() ,Python将忽略Car 类中的方法fill_gas_tank() ,转而运行上述代码。使用继承时,可让子类保留从父类那里继承而来的精华,并剔除不需要的糟粕。

9.3.5 将实例用作属性

使用代码模拟实物时,你可能会发现自己给类添加的细节越来越多:属性和方法清单以及文件都越来越长。在这种情况下,可能需要将类的一部分作为一个独立的类提取出来。你可以将大型类拆分成多个协同工作的小类。

例如,不断给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

    def read_odometer(self):
        print("This car has " + str(self.odometer_reading) + " miles on it.")

    def update_odometer(mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
    
    def increment_odometer(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()

我们定义了一个名为Battery 的新类,它没有继承任何类。每个ElectricCar 实例都包含一个自动创建的Battery 实例。

我们创建一辆电动汽车,并将其存储在变量my_tesla 中。要描述电瓶时,需要使用电动汽车的属性battery,这时属性时Battery类的一个实例,于是可以使用Battery类的一个方法:describe.battery()

my_tesla.battery.describe_battery()

这看似做了很多额外的工作,但现在我们想多详细地描述电瓶都可以,且不会导致ElectricCar 类混乱不堪。下面再给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 = str(self.year) + " " + self.make + " " + self.model
        return long_name

    def read_odometer(self):
        print("This car has " + str(self.odometer_reading) + " miles on it.")

    def update_odometer(mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
    
    def increment_odometer(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.")

    def get_range(self):
    	"""根据电瓶容量确定最大行驶里程"""
        if self.battery_size == 70:
            range = 240
        elif self.battery_size == 85:
            range = 270
        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_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
my_tesla.battery.get_range()

输出:

2016 tesla model s
This car has a 70 -KWh battery.
This car can go approximately 240 miles on a full charge.
9.4 导入类

随着你不断地给类添加功能,文件可能变得很长,即便你妥善地使用了继承亦如此。为遵循Python的总体理念,应让文件尽可能整洁。为在这方面提供帮助,Python允许你将类存储在模块中,然后在主程序中导入所需的模块。

9.4.1 导入单个类

下面来创建一个只包含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_descriptive_name(self):
        """返回整洁的描述性名称"""
        long_name = str(self.year) + " " + self.make + " " + self.model
        return long_name

    def read_odometer(self):
        """打印一条消息,指出汽车的里程"""
        print("This car has " + str(self.odometer_reading) + " miles on it.")

    def update_odometer(mileage):
        """ 
        将里程表读数设置为指定的值
        拒绝将里程表往回拨
        """
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
    
    def increment_odometer(miles):
        """将里程表读数增加指定的量"""
        self.odometer_reading += miles

下面来创建另一个文件:my_car.py,在其中导入Car 类并创建其实例:
my_car.py

from car import Car

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()
9.4.2 在一个模块中存储多个类

虽然同一个模块中的类之间应存在某种相关性,但可根据需要在一个模块中存储任意数量的类。类Battery 和ElectricCar 都可帮助模拟汽车,因此下面将它们都加入模块car.py中:
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_descriptive_name(self):
        """返回整洁的描述性名称"""
        long_name = str(self.year) + " " + self.make + " " + self.model
        return long_name

    def read_odometer(self):
        """打印一条消息,指出汽车的里程"""
        print("This car has " + str(self.odometer_reading) + " miles on it.")

    def update_odometer(mileage):
        """ 
        将里程表读数设置为指定的值
        拒绝将里程表往回拨
        """
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
    
    def increment_odometer(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.")

    def get_range(self):
        """打印一条描述电瓶续航里程的消息"""
        if self.battery_size == 70:
            range = 240
        elif self.battery_size == 85:
            range = 270
        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的文件,导入ElectricCar 类,并创建一辆电动汽车了:
my_electric_car.py

from car import ElectricCar

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

输出:

2016 tesla model s
This car has a 70-kWh battery.
This car can go approximately 240 miles on a full charge.
9.4.3 从一个模块中导入多个类

可根据需要在程序文件中导入任意数量的类。如果我们要在同一个程序中创建普通汽车和电动汽车,就需要将Car 和ElectricCar 类都导入:
my_cars.py

from car import ElectricCar, Car

my_beetle = Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())

my_tesla = ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())
9.4.4

你还可以导入整个模块,再使用句点表示法访问需要的类。这种导入方法很简单,代码也易于阅读。由于创建类实例的代码都包含模块名,因此不会与当前文件使用的任何名称发生冲突。
my_cars.py

import car

my_beetle = car.Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())

my_tesla = car.ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())

我们导入了整个car 模块,使用语法 module_name.class_name 访问需要的类。

9.4.5 导入模块中的所有类

要导入模块中的每个类,可使用下面的语法:

from module_name import *

不推荐使用这种导入方式,其原因有二。首先,如果只要看一下文件开头的import 语句,就能清楚地知道程序使用了哪些类,将大有裨益;但这种导入方式没有明确地指出你使用了模块中的哪些类。这种导入方式还可能引发名称方面的困惑。如果你不小心导入了一个与程序文件中其他东西同名的类,将引发难以诊断的错误。这里之所以介绍这种导入方式,是因为虽然不推荐使用这种方式,但你可能会在别人编写的代码中见到它。

需要从一个模块中导入很多类时,最好导入整个模块,并使用 module_name.class_name 语法来访问类。这样做时,虽然文件开头并没有列出用到的所有类,但你清楚地知道在程序的哪些地方使用了导入的模块;你还避免了导入模块中的每个类可能引发的名称冲突。

9.4.6 在一个模块中导入另一个模块

有时候,需要将类分散到多个模块中,以免模块太大,或在同一个模块中存储不相关的类。将类存储在多个模块中时,你可能会发现一个模块中的类依赖于另一个模块中的类。在这种情况下,可在前一个模块中导入必要的类。

例如,下面将Car 类存储在一个模块中,并将ElectricCar 和Battery 类存储在另一个模块中。我们将第二个模块命名为electric_car.py ,并将Battery 和ElectricCar 类复制到这个模块中:
electric_car.py

"""一组可用于表示电动汽车的类"""
from car import Car

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.")

    def get_range(self):
        """打印一条描述电瓶续航里程的消息"""
        if self.battery_size == 70:
            range = 240
        elif self.battery_size == 85:
            range = 270
        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()

更新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_descriptive_name(self):
        """返回整洁的描述性名称"""
        long_name = str(self.year) + " " + self.make + " " + self.model
        return long_name

    def read_odometer(self):
        """打印一条消息,指出汽车的里程"""
        print("This car has " + str(self.odometer_reading) + " miles on it.")

    def update_odometer(mileage):
        """ 
        将里程表读数设置为指定的值
        拒绝将里程表往回拨
        """
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
    
    def increment_odometer(miles):
        """将里程表读数增加指定的量"""
        self.odometer_reading += miles

my_cars.py

from car import Car
from electric_car import ElectricCar

my_beetle = Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())
my_tesla = ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())
9.4.7 自定义工作流程

一开始应让代码结构尽可能简单。先尽可能在一个文件中完成所有的工作,确定一切都能正确运行后,再将类移到独立的模块中。如果你喜欢模块和文件的交互方式,可在项目开始时就尝试将类存储到模块中。先找出让你能够编写出可行代码的方式,再尝试让代码更为组织有序。

9.5 Python标准库

Python标准库 是一组模块,安装的Python都包含它。。下面来看模块collections 中的一个类——OrderedDict 。

字典让你能够将信息关联起来,但它们不记录你添加键—值对的顺序。要创建字典并记录其中的键—值对的添加顺序,可使用模块collections 中的OrderedDict 类。OrderedDict 实例的行为几乎与字典相同,区别只在于记录了键—值对的添加顺序。
favorite_language.py

from collections import OrderedDict

favorite_languages = OrderedDict()
favorite_languages['jen'] = 'python'
favorite_languages['sarah'] = 'c'
favorite_languages['edward'] = 'ruby'
favorite_languages['phil'] = 'python'
for name, language in favorite_languages.items():
	print(name.title() + "'s favorite language is " + language.title() + ".")

输出:

Jen's favorite language is Python.
Sarah's favorite language is C.
Edward's favorite language is Ruby.
Phil's favorite language is Python.
9.6 类编码风格

类名应采用驼峰命名法 ,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。

对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。

可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。

需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import 语句,再添加一个空行,然后编写导入你自己编写的模块的import 语句。在包含多条import 语句的程序中,这种做法让人更容易明白程序使用的各个模块都来自何方。

习题
9-1
class Restaurant():
    def __init__(self, restaurant_name, cuisine_type):
        self.restaurant_name = restaurant_name
        self.cuisine_type = cuisine_type

    def describe_restaurant(self):
        print("The name of this restaurant is " + self.restaurant_name +".The cuisine_type is "+ self.cuisine_type + ".")
    
    def open_restaurant(self):
        print("The restaurant is available now!")

restaurant = Restaurant('Chaoyixing', 'Lucai')
restaurant.describe_restaurant()
restaurant.open_restaurant()
9-3
class User():
    def __init__(self, first_name, last_name, age, country):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.country = country
    
    def describe_user(self):
        long_name = self.first_name.title() + " " + self.last_name.title() + " "
        long_name += str(self.age) + " " + self.country
        print(long_name)

    def greet_user(self):
        print("Hello, " + self.first_name.title() + " " + self.last_name.title() + ".")

admin = User('bruce', 'zhang', 20, 'China')
admin.describe_user()
admin.greet_user()

user1 = User('jack', 'ma', 50, 'Amercia')
user1.describe_user()
user1.greet_user()
9-4
class Restaurant():
    def __init__(self, restaurant_name, cuisine_type):
        """初始化描述餐馆的属性"""
        self.restaurant_name = restaurant_name
        self.cuisine_type = cuisine_type
        self.number_saved = 0

    def describe_restaurant(self):
        """对餐馆名和菜系进行描述"""
        print("The name of this restaurant is " + self.restaurant_name +".The cuisine_type is "+ self.cuisine_type + ".")
    
    def open_restaurant(self):
        """当前餐馆正在营业"""
        print("The restaurant is available now!")

    def read_number_saved(self):
        """读取当前就餐人数"""
        if self.number_saved == 0:
            print("There is no people eating now.")
        elif self.number_saved == 1:
            print("There is 1 person eating now.")
        elif self.number_saved >= 2:
            print("There are " + str(self.number_saved) + " persons eating now.")

    def increment_number_saved(self, increment_numbers):
        """就餐人数增加指定的量"""
        self.number_saved += increment_numbers

    def set_number_saved(self, persons):
        """设置就餐人数"""
        self.number_saved = persons

restaurant = Restaurant('Chaoyixing', 'Lucai')
restaurant.describe_restaurant()
restaurant.read_number_saved()
restaurant.set_number_saved(10)
restaurant.read_number_saved()
restaurant.increment_number_saved(2)
restaurant.read_number_saved()
9-5
class User():
    def __init__(self, first_name, last_name, age, country, login_attemps):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.country = country
        self.login_attemps = login_attemps
    
    def describe_user(self):
        """对用户的信息进行描述"""
        long_name = self.first_name.title() + " " + self.last_name.title() + " "
        long_name += str(self.age) + " " + self.country
        print(long_name)

    def greet_user(self):
        """欢迎用户"""
        print("Hello, " + self.first_name.title() + " " + self.last_name.title() + ".")

    def read_login_attempts(self):
        print(str(self.login_attemps))
    
    def increment_login_attemps(self):
        self.login_attemps += 1

    def reset_login_attemps(self):
        self.login_attemps = 0

admin = User('bruce', 'zhang', 20, 'China', 3)
for i in range(4):
    admin.increment_login_attemps()
admin.read_login_attempts()
admin.reset_login_attemps()
admin.read_login_attempts()
9-6
class Restaurant():
    def __init__(self, restaurant_name, cuisine_type):
        """初始化描述餐馆的属性"""
        self.restaurant_name = restaurant_name
        self.cuisine_type = cuisine_type
        self.number_saved = 0

    def describe_restaurant(self):
        """对餐馆名和菜系进行描述"""
        print("The name of this restaurant is " + self.restaurant_name +".The cuisine_type is "+ self.cuisine_type + ".")
    
    def open_restaurant(self):
        """当前餐馆正在营业"""
        print("The restaurant is available now!")

    def read_number_saved(self):
        """读取当前就餐人数"""
        if self.number_saved == 0:
            print("There is no people eating now.")
        elif self.number_saved == 1:
            print("There is 1 person eating now.")
        elif self.number_saved >= 2:
            print("There are " + str(self.number_saved) + " persons eating now.")

    def increment_number_saved(self, increment_numbers):
        """就餐人数增加指定的量"""
        self.number_saved += increment_numbers

    def set_number_saved(self, persons):
        """设置就餐人数"""
        self.number_saved = persons

class IceCreamStand(Restaurant):
    def __init__(self, restaurant_name, cuisine_type):
        super().__init__(restaurant_name, cuisine_type)
        # 这里我容易犯一个错误,super().__init__(self, restaurant_name, cuisine_type)
        self.flavors = ['apple', 'strawberry', 'pear']
    
    def show_flavors(self):
        print("There are several flavors:")
        for flavor in self.flavors:
            print("-" + flavor)

new_ice_cream = IceCreamStand('mixuebingcheng', 'fruit')
new_ice_cream.show_flavors()
9-7
class User():
    def __init__(self, first_name, last_name, age, country, login_attemps):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.country = country
        self.login_attemps = login_attemps
    
    def describe_user(self):
        """对用户的信息进行描述"""
        long_name = self.first_name.title() + " " + self.last_name.title() + " "
        long_name += str(self.age) + " " + self.country
        print(long_name)

    def greet_user(self):
        """欢迎用户"""
        print("Hello, " + self.first_name.title() + " " + self.last_name.title() + ".")

    def read_login_attempts(self):
        print(str(self.login_attemps))
    
    def increment_login_attemps(self):
        self.login_attemps += 1

    def reset_login_attemps(self):
        self.login_attemps = 0

class Admin(User):
    def __init__(self, first_name, last_name, age, country, login_attemps):
        super().__init__(first_name, last_name, age, country, login_attemps)
        self.privileges = ['can add post', 'can delete post', 'can ban user']

    def show_privileges(self):
        print("You have these privileges:")
        for privilege in self.privileges:
            print("-" + privilege)

master = Admin('bruce', 'zhang', 20, 'China', 1)
master.show_privileges()
9-8
class User():
    def __init__(self, first_name, last_name, age, country, login_attemps):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.country = country
        self.login_attemps = login_attemps
    
    def describe_user(self):
        """对用户的信息进行描述"""
        long_name = self.first_name.title() + " " + self.last_name.title() + " "
        long_name += str(self.age) + " " + self.country
        print(long_name)

    def greet_user(self):
        """欢迎用户"""
        print("Hello, " + self.first_name.title() + " " + self.last_name.title() + ".")

    def read_login_attempts(self):
        print(str(self.login_attemps))
    
    def increment_login_attemps(self):
        self.login_attemps += 1

    def reset_login_attemps(self):
        self.login_attemps = 0

class Privilege():
    def __init__(self):
        self.privileges = ['can add post', 'can delete post', 'can ban user']

    def show_privileges(self):
        print("You have these privileges:")
        for privilege in self.privileges:
            print("-" + privilege)

class Admin(User):
    def __init__(self, first_name, last_name, age, country, login_attemps):
        super().__init__(first_name, last_name, age, country, login_attemps)
        self.privileges = Privilege()


master = Admin('bruce', 'zhang', 20, 'China', 1)
master.privileges.show_privileges()
9-9
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.")

    def upgrade_battery(self):
        if self.battery_size != 85:
            self.battery_size = 85

    def get_range(self):
        """打印一条消息,指出电瓶的续航里程"""
        if self.battery_size == 70:
            range = 240
        elif self.battery_size == 85:
            range = 270
        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_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.get_range()
my_tesla.battery.upgrade_battery()
my_tesla.battery.get_range()
9-10

restaurant.py

class Restaurant():
    def __init__(self, restaurant_name, cuisine_type):
        """初始化描述餐馆的属性"""
        self.restaurant_name = restaurant_name
        self.cuisine_type = cuisine_type
        self.number_saved = 0

    def describe_restaurant(self):
        """对餐馆名和菜系进行描述"""
        print("The name of this restaurant is " + self.restaurant_name +".The cuisine_type is "+ self.cuisine_type + ".")
    
    def open_restaurant(self):
        """当前餐馆正在营业"""
        print("The restaurant is available now!")

    def read_number_saved(self):
        """读取当前就餐人数"""
        if self.number_saved == 0:
            print("There is no people eating now.")
        elif self.number_saved == 1:
            print("There is 1 person eating now.")
        elif self.number_saved >= 2:
            print("There are " + str(self.number_saved) + " persons eating now.")

    def increment_number_saved(self, increment_numbers):
        """就餐人数增加指定的量"""
        self.number_saved += increment_numbers

    def set_number_saved(self, persons):
        """设置就餐人数"""
        self.number_saved = persons

new_restaurant.py

from restaurant import Restaurant

real_me = Restaurant('chaoyixing', 'lucai')
real_me.describe_restaurant()
9-11

website.py

class User():
    def __init__(self, first_name, last_name, age, country, login_attemps):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.country = country
        self.login_attemps = login_attemps
    
    def describe_user(self):
        """对用户的信息进行描述"""
        long_name = self.first_name.title() + " " + self.last_name.title() + " "
        long_name += str(self.age) + " " + self.country
        print(long_name)

    def greet_user(self):
        """欢迎用户"""
        print("Hello, " + self.first_name.title() + " " + self.last_name.title() + ".")

    def read_login_attempts(self):
        print(str(self.login_attemps))
    
    def increment_login_attemps(self):
        self.login_attemps += 1

    def reset_login_attemps(self):
        self.login_attemps = 0

class Privilege():
    def __init__(self):
        self.privileges = ['can add post', 'can delete post', 'can ban user']

    def show_privileges(self):
        print("You have these privileges:")
        for privilege in self.privileges:
            print("-" + privilege)

class Admin(User):
    def __init__(self, first_name, last_name, age, country, login_attemps):
        super().__init__(first_name, last_name, age, country, login_attemps)
        self.privileges = Privilege()

manage.py

from website import Admin

master = Admin('bruce', 'zhang', 20, 'China', 1)
master.privileges.show_privileges()
9-12

user.py

class User():
    def __init__(self, first_name, last_name, age, country, login_attemps):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.country = country
        self.login_attemps = login_attemps
    
    def describe_user(self):
        """对用户的信息进行描述"""
        long_name = self.first_name.title() + " " + self.last_name.title() + " "
        long_name += str(self.age) + " " + self.country
        print(long_name)

    def greet_user(self):
        """欢迎用户"""
        print("Hello, " + self.first_name.title() + " " + self.last_name.title() + ".")

    def read_login_attempts(self):
        print(str(self.login_attemps))
    
    def increment_login_attemps(self):
        self.login_attemps += 1

    def reset_login_attemps(self):
        self.login_attemps = 0

manage.py

from user import User

class Privilege():
    def __init__(self):
        self.privileges = ['can add post', 'can delete post', 'can ban user']

    def show_privileges(self):
        print("You have these privileges:")
        for privilege in self.privileges:
            print("-" + privilege)

class Admin(User):
    def __init__(self, first_name, last_name, age, country, login_attemps):
        super().__init__(first_name, last_name, age, country, login_attemps)
        self.privileges = Privilege()

real_work.py

from user import User
from manage import Admin

master = Admin('bruce', 'zhang', 20, 'China', 1)
master.privileges.show_privileges()
9-13
from collections import OrderedDict

program_vocabulary = OrderedDict()
program_vocabulary['print'] = '打印'
program_vocabulary['variable'] = '变量'
program_vocabulary['set'] = '集合'
program_vocabulary['list'] = '列表'
program_vocabulary['dict'] = '字典'

for vocabulary, meaning in program_vocabulary.items():
    print("\n" + vocabulary + ":\n\t" + meaning)
9-14
from random import randint

class Die():
    def __init__(self, sides=6):
        self.sides = sides

    def roll_die(self, time=10):
        print("with the "+ str(self.sides) + " sides dice,play in " + str(time) + " times:" )
        for i in range(time):
            self.result = randint(1, self.sides)
            print("THe " + str(i+1) + " time:" + "You get a result:" + str(self.result))


s1 = Die(6)
s1.roll_die()

s2 = Die(10)
s2.roll_die()

s3 = Die(20)
s3.roll_die()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值