目录
编辑
9.4.2 在一个模块中存储多个类
虽然同一个模块中的类之间应存在某种相关性,但可根据需要在一个模块中存储任意数量的 类。类Battery和ElectricCar都可帮助模拟汽车,因此下面将它们都加入模块car.py中: car.py
my_electric_car.py
9.4.3 从一个模块中导入多个类
9.4.4 导入整个模块
my_cars.py
在1处,我们导入了整个car模块。接下来,我们使用语法module_name.class_name访问需要 的类。像前面一样,我们在2处创建了一辆大众甲壳虫汽车,并在3处创建了一辆特斯拉Roadster 汽车。
9.4.5 导入模块中的所有类
9.4.6 在一个模块中导入另一个模块
electric_car.py
car.py
my_cars.py
9.4.7 自定义工作流程
9.5 Python 标准库
favorite_languages.py
9.6 类编码风格
9.7 小结
往期快速传送门(在文章最后):
感谢大家的支持!欢迎订阅收藏!专栏将持续更新!
虽然同一个模块中的类之间应存在某种相关性,但可根据需要在一个模块中存储任意数量的 类。类Battery和ElectricCar都可帮助模拟汽车,因此下面将它们都加入模块car.py中: car.py
"""一组用于表示燃油汽车和电动汽车的类"""
class Car():
--snip--
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
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.
可根据需要在程序文件中导入任意数量的类。如果我们要在同一个程序中创建普通汽车和电 动汽车,就需要将Car和ElectricCar类都导入:
my_cars.py
1 from car import Car, ElectricCar
2 my_beetle = Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())
3 my_tesla = ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())
在1处从一个模块中导入多个类时,用逗号分隔了各个类。导入必要的类后,就可根据需要 创建每个类的任意数量的实例。
在这个示例中,我们在2处创建了一辆大众甲壳虫普通汽车,并在3处创建了一辆特斯拉 Roadster电动汽车:
2016 Volkswagen Beetle
2016 Tesla Roadster
你还可以导入整个模块,再使用句点表示法访问需要的类。这种导入方法很简单,代码也易 于阅读。由于创建类实例的代码都包含模块名,因此不会与当前文件使用的任何名称发生冲突。 下面的代码导入整个car模块,并创建一辆普通汽车和一辆电动汽车:
my_cars.py
1 import car
2 my_beetle = car.Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())
3 my_tesla = car.ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())
在1处,我们导入了整个car模块。接下来,我们使用语法module_name.class_name访问需要 的类。像前面一样,我们在2处创建了一辆大众甲壳虫汽车,并在3处创建了一辆特斯拉Roadster 汽车。
要导入模块中的每个类,可使用下面的语法:
from module_name import
不推荐使用这种导入方式,其原因有二。首先,如果只要看一下文件开头的import语句,就 能清楚地知道程序使用了哪些类,将大有裨益;但这种导入方式没有明确地指出你使用了模块中 的哪些类。这种导入方式还可能引发名称方面的困惑。如果你不小心导入了一个与程序文件中其 他东西同名的类,将引发难以诊断的错误。这里之所以介绍这种导入方式,是因为虽然不推荐使 用这种方式,但你可能会在别人编写的代码中见到它。
需要从一个模块中导入很多类时,最好导入整个模块,并使用module_name.class_name语法 来访问类。这样做时,虽然文件开头并没有列出用到的所有类,但你清楚地知道在程序的哪些地 方使用了导入的模块;你还避免了导入模块中的每个类可能引发的名称冲突。
有时候,需要将类分散到多个模块中,以免模块太大,或在同一个模块中存储不相关的类。 将类存储在多个模块中时,你可能会发现一个模块中的类依赖于另一个模块中的类。在这种情况 下,可在前一个模块中导入必要的类。 例如,下面将Car类存储在一个模块中,并将ElectricCar和Battery类存储在另一个模块中。 我们将第二个模块命名为electric_car.py(这将覆盖前面创建的文件electric_car.py),并将Battery和ElectricCar类复制到这个模块中:
electric_car.py
"""一组可用于表示电动汽车的类"""
1 from car import Car
class Battery():
--snip--
class ElectricCar(Car):
--snip--
ElectricCar类需要访问其父类Car,因此在1处,我们直接将Car类导入该模块中。如果我们 忘记了这行代码,Python将在我们试图创建ElectricCar实例时引发错误。我们还需要更新模块 car,使其包含Car类:
car.py
"""一个可用于表示汽车的类"""
class Car():
--snip--
现在可以分别从每个模块中导入类,以根据需要创建任何类型的汽车了:
my_cars.py
1 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())
在1处,我们从模块car中导入了Car类,并从模块electric_car中导入ElectricCar类。接下 来,我们创建了一辆普通汽车和一辆电动汽车。这两种汽车都得以正确地创建:
2016 Volkswagen Beetle
2016 Tesla Roadster
正如你看到的,在组织大型项目的代码方面,Python提供了很多选项。熟悉所有这些选项很 重要,这样你才能确定哪种项目组织方式是最佳的,并能理解别人开发的项目。 一开始应让代码结构尽可能简单。先尽可能在一个文件中完成所有的工作,确定一切都能正确运行后,再将类移到独立的模块中。如果你喜欢模块和文件的交互方式,可在项目开始时就尝 试将类存储到模块中。先找出让你能够编写出可行代码的方式,再尝试让代码更为组织有序。
Python标准库是一组模块,安装的Python都包含它。你现在对类的工作原理已有大致的了解, 可以开始使用其他程序员编写好的模块了。可使用标准库中的任何函数和类,为此只需在程序开 头包含一条简单的import语句。下面来看模块collections中的一个类——OrderedDict。 字典让你能够将信息关联起来,但它们不记录你添加键—值对的顺序。要创建字典并记录其 中的键—值对的添加顺序,可使用模块collections中的OrderedDict类。OrderedDict实例的行为 几乎与字典相同,区别只在于记录了键—值对的添加顺序。 我们再来看一看第6章的favorite_languages.py示例,但这次将记录被调查者参与调查的 顺序:
favorite_languages.py
1 from collections import OrderedDict
2 favorite_languages = OrderedDict()
3 favorite_languages['jen'] = 'python'
favorite_languages['sarah'] = 'c'
favorite_languages['edward'] = 'ruby'
favorite_languages['phil'] = 'python'
4 for name, language in favorite_languages.items():
print(name.title() + "'s favorite language is " +
language.title() + ".")
我们首先从模块collections中导入了OrderedDict类(见1)。在2处,我们创建了OrderedDict 类的一个实例,并将其存储到favorite_languages中。请注意,这里没有使用花括号,而是调用 OrderedDict()来创建一个空的有序字典,并将其存储在favorite_languages中。接下来,我们以 每次一对的方式添加名字—语言对(见3)。在4处,我们遍历favorite_languages,但知道将以 添加的顺序获取调查结果:
Jen's favorite language is Python.
Sarah's favorite language is C.
Edward's favorite language is Ruby.
Phil's favorite language is Python.
这是一个很不错的类,它兼具列表和字典的主要优点(在将信息关联起来的同时保留原来的 顺序)。等你开始对关心的现实情形建模时,可能会发现有序字典正好能够满足需求。随着你对 标准库的了解越来越深入,将熟悉大量可帮助你处理常见情形的模块。
注意 你还可以从其他地方下载外部模块。本书第二部分的每个项目都需要使用外部模块,届 时你将看到很多这样的示例。
你必须熟悉有些与类相关的编码风格问题,在你编写的程序较复杂时尤其如此。
类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名 和模块名都采用小写格式,并在单词之间加上下划线。
对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的 功能,并遵循编写函数的文档字符串时采用的格式约定。每个模块也都应包含一个文档字符串, 对其中的类可用于做什么进行描述。
可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中, 可使用两个空行来分隔类。
需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import语句,再 添加一个空行,然后编写导入你自己编写的模块的import语句。在包含多条import语句的程序中, 这种做法让人更容易明白程序使用的各个模块都来自何方。
在本章中,你学习了:如何编写类;如何使用属性在类中存储信息,以及如何编写方法,以 让类具备所需的行为;如何编写方法__init__(),以便根据类创建包含所需属性的实例。你见识 了如何修改实例的属性——包括直接修改以及通过方法进行修改。你还了解了:使用继承可简化 相关类的创建工作;将一个类的实例用作另一个类的属性可让类更简洁。 你了解到,通过将类存储在模块中,并在需要使用这些类的文件中导入它们,可让项目组织 有序。你学习了Python标准库,并见识了一个使用模块collections中的OrderedDict类的示例。 最后,你学习了编写类时应遵循的Python约定。 在第10章中,你将学习如何使用文件,这让你能够保存你在程序中所做的工作,以及你让用户 做的工作。你还将学习异常,这是一种特殊的Python类,用于帮助你在发生错误时采取相应的措施
关于“Python”的核心知识点整理大全12-CSDN博客