热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python基础篇(十六)——类(下)

前言  前两篇文章给大家介绍了Python中的类,主要包括类的创建和使用、以及类中较为重要的一个知识点——继承。本文给大家介绍Python中将类的导入、Python的标准

前言

  前两篇文章给大家介绍了Python中的类,主要包括类的创建和使用、以及类中较为重要的一个知识点——继承。本文给大家介绍Python中将类的导入、Python的标准库以及Python在类中的编码风格。首先为大家介绍导入类的相关内容。

一、导入类

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

1、导入单个类

  下面来创建一个只包含Car类的模块。这让我们面临一个微妙的命名问题:在本章中,已经有一个名为Car.py的文件,但这个模块也应命名为car.py,因为它包含表示汽车的代码。我们将这样解决这个命名的问题:将car类存储在一个名为car.py的模块中,该模块将覆盖前面使用的文件car.py。从现在开始,使用该模块的程序都必须使用更具体的文件名,如my_car.py,下面是car.py,其中只包含Car类的代码:

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("Your can't roll back an odometer!")
    def increment_odoemeter(self, miles):
        """将里程表读数增加指定的量"""
        self.odometer_reading += miles

  我们在本代码中,只包含了一个模块级文档字符串,对该模块的内容做了简要的描述,你应为自己创建的每个模块都编写文档字符串。下面我们来创建另一个文件——my_car.py,在其中导入Car类并创建其实例,具体如下:

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

  我们首先将用import语句让Python打开模块car,并导入其中的Car类。这样我们就可以使用Car类了,就像它是在这个文件中定义一样。输出与我们在前面看到的一样,具体执行结果如下:

python基础篇(十六)——类(下)

  导入类是一种有效的编程方式。如果在这个程序中包含了整个Car类,它该有多长。通过将这个类移动到一个模块中,并导入该模块,我们依然可以使用其所有功能,但主程序文件变得整洁而易于阅读了。这还能让我们将大部分逻辑存储在独立的文件中;确定类像我们希望的那样工作后,我们就可以不管这些文件,而专注于主程序的高级逻辑了。

2、在一个模块中存储多个类

  虽然同一个模块的类之间应存在某种相关性,但可根据需要在一个模块中存储任意数量的类。类BatteryElectricCar都可帮助模拟汽车,因此下面都将加入模块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.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("Your can't roll back an odometer!")
    def increment_odoemeter(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 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_size = 70
        self.battery = Battery()  

  现在,我们可以新建一个名为my_electric_car.py的文件,导入ElectricCar类,并创建一辆电动汽车了,具体实现如下:

from car import ElectricCar
my_tesla = ElectricCar('tesla', 'models', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
my_tesla.battery.get_range()

  输出与我们前面看到的相同,但大部分逻辑都隐藏在一个模块中,具体执行结果如下:

python基础篇(十六)——类(下)

3、从一个模块中导入多个类

  可根据需要在程序文件中导入任意数量的类。如果我们要在同一个程序中创建普通汽车和电动汽车,就需要将CarElectricCar类都导入,具体实现如下:

from car import Car, 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())

  我们从一个模块中导入多个模块,用逗号隔开了各个类。导入必要的类后,就可根据需要创建吗每个类的任意数量的实例。在这个示例中,我们创建了一辆大众甲壳虫普通汽车,并又创建了一辆特斯拉电动汽车,具体执行结果如下:

python基础篇(十六)——类(下)

4、导入整个模块

  我们其实还可以导入整个模块,在使用句点表示法访问需要的类。这种导入方法很简单,代码也容易阅读。由于创建类实例的代码都包含模块名,因此不会与当前文件使用的任何名称发生冲突。下面的代码导入整个car模块,并创建一辆普通汽车和一辆电动汽车,具体实现如下:

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()访问需要的类。像前面一样,我们创建了一辆大众和一辆特斯拉汽车,具体执行结果如下:

python基础篇(十六)——类(下)

5、导入模块中的所有类

  要导入模块中的 每个类,可使用语法from module_name import *。但是不推荐这种导入方法,其原因有二。首先,如果只要看一下文件开头的import语句,就能清楚地知道程序使用了哪些类,将大有裨益;但这种导入方式没有明确地指出我们使用了模块中的那些类。这种导入方法还可能引发名称方面的困惑。如果我们不小心导入了一个与程序文件中其他东西同名的类,将引发难以诊断的错误。这里之所以介绍这种导入方法,是因为虽然不推荐使用这种方法,但我们可能会在别人编写的代码中见到它。
  需要从一个模块中导入很多类时,最好导入整个模块,并使用module_name.class_name语法来访问类。这样做时,虽然文件开头并没有列出用到的所有类,但我们清楚地知道在程序的哪些地方使用了导入的模块;我们还避免了导入模块中的每个类可能引发的名称冲突。

6、在一个模块中导入另一个模块

  有时候,需要将类分散到多个模块中,并将ElectricCarBattery类存储在另一个模块中。在这种情况下,可在前一个模块中导入必要的类。例如,下面的Car类存储在一个模块中,并将ElectricCarBattery类存储在另一个模块中。我们将第二个模块命名为electric_car.py(这将覆盖前面创建的文件electric_car.py文件),并将ElectricCarBattery类复制在这个模块中:

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_size = 70
        self.battery = Battery()

  ElectricCar类需要访问父类Car,因此,我们直接将Car类导入该模块中。如果我们忘记了这行代码,Python将在我们试图创建ElectricCar实例时引发错误。我们还需要更新模块car,使其包含Car类:

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("Your can't roll back an odometer!")
    def increment_odoemeter(self, miles):
        """将里程表读数增加指定的量"""
        self.odometer_reading += miles

  现在可以分别从每个模块中导入类,以根据需要创建任何类型的汽车了:

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

  我们从模块car中导入了Car类,并从模块electric_car中导入了ElectricCar类,接下来我们创建了一辆普通的汽车和一辆电动汽车。这两种汽车得以正确地创建,具体执行结果如下:

python基础篇(十六)——类(下)

7、自定义工作流程

  正如我们看到的,再组甚至大型项目的代码方面,Python提供了很多选项。熟悉所有这些选项很重要,这样我们才能确定那种项目组织方式是最佳的,并能理解别人开发的项目。
  一开始应让代码结构尽可能简单。先尽可能在一个文件中完成所有的工作,确定一切都能正确运行后,再将类移动到独立的模块中。如果我们喜欢模块和文件的交互方式,可在项目开始时就尝试将类存储到模块中。先找出让我们能够编写出可行代码的方式,在尝试让代码更为组织有序。

二、Python标准库

  Python标准库是一组模块,安装的Python都包含它。我们现在对类的工作原理已有大致的了解,可以开始使用其他程序员编写好的模块了。可使用标准库中的任何函数和类,为此只需在程序开头包含一条简单的import语句。
  字典让我们能够将信息关联起来,但它们不记录我们添加键值对的顺序。要创建字典并记录其中的键值对的添加顺序,可使用模块collections中的OrderedDict类。OrderedDict实例的行为几乎和字典相同,区别只在于记录了键值对的添加顺序。
  这是一个很不错的类,它兼具列表和字典的主要优点(在将信息关联起来的同时保留原来的顺序)。等我们开始对关心的现实情形建模时,可能会发现有序字典正好能够满足需求。随着我们对标准库的了解越来越深入,将熟悉大量可帮助我们处理常见情形的模块。当然,我们也可以从其他地方下载外部模块。我们在以后介绍的爬虫、推荐系统以及机器学习的实战中经常会应用下载好的模块。

三、类的编码风格

  我们必须熟悉有些与类相关的编码风格的问题,在我们编写的程序较复杂的时尤其如此。类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。每个模块也都包含一个文档字符串,对其中的类可用于做什么进行描述。可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import语句的程序中,这种做法让人更容易明白程序 使用的各个模块都来自何方。

总结

  我们通过三篇文章给大家介绍了Python中的类,主要包括类的创建和使用、以及类中较为重要的一个知识点——继承。本文给大家介绍Python中将类的导入、Python的标准库以及Python在类中的编码风格。Python是一门注重实际操作的语言,它是众多编程语言中最简单,也是最好入门的。当你把这门语言学会了,再去学习java、go以及C语言就比较简单了。当然,Python也是一门热门语言,对于人工智能的实现有着很大的帮助,因此,值得大家花时间去学习。生命不息,奋斗不止,我们每天努力,好好学习,不断提高自己的能力,相信自己一定会学有所获。加油!!!


推荐阅读
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了基于c语言的mcs51单片机定时器计数器的应用教程,包括定时器的设置和计数方法,以及中断函数的使用。同时介绍了定时器应用的举例,包括定时器中断函数的编写和频率值的计算方法。主函数中设置了T0模式和T1计数的初值,并开启了T0和T1的中断,最后启动了CPU中断。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Day2列表、字典、集合操作详解
    本文详细介绍了列表、字典、集合的操作方法,包括定义列表、访问列表元素、字符串操作、字典操作、集合操作、文件操作、字符编码与转码等内容。内容详实,适合初学者参考。 ... [详细]
  • 这篇文章主要介绍了Python拼接字符串的七种方式,包括使用%、format()、join()、f-string等方法。每种方法都有其特点和限制,通过本文的介绍可以帮助读者更好地理解和运用字符串拼接的技巧。 ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • C语言判断正整数能否被整除的程序
    本文介绍了使用C语言编写的判断正整数能否被整除的程序,包括输入一个三位正整数,判断是否能被3整除且至少包含数字3的方法。同时还介绍了使用qsort函数进行快速排序的算法。 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
  • C语言常量与变量的深入理解及其影响
    本文深入讲解了C语言中常量与变量的概念及其深入实质,强调了对常量和变量的理解对于学习指针等后续内容的重要性。详细介绍了常量的分类和特点,以及变量的定义和分类。同时指出了常量和变量在程序中的作用及其对内存空间的影响,类似于const关键字的只读属性。此外,还提及了常量和变量在实际应用中可能出现的问题,如段错误和野指针。 ... [详细]
author-avatar
台球吴蒙蒙向_521
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有