关于“Python”的核心知识点整理大全21

9.3.2 Python 2.7 中的继承

在Python 2.7中,继承语法稍有不同,ElectricCar类的定义类似于下面这样:

class Car(object):def __init__(self, make, model, year):--snip--
class ElectricCar(Car):def __init__(self, make, model, year):super(ElectricCar, self).__init__(make, model, year)--snip-- 

函数super()需要两个实参:子类名和对象self。为帮助Python将父类和子类关联起来,这些 实参必不可少。另外,在Python 2.7中使用继承时,务必在定义父类时在括号内指定object。

9.3.3 给子类定义属性和方法

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

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

class Car():--snip--
class ElectricCar(Car):"""Represent aspects of a car, specific to electric vehicles."""def __init__(self, make, model, year):"""
电动汽车的独特之处
初始化父类的属性,再初始化电动汽车特有的属性"""super().__init__(make, model, year)
1 self.battery_size = 70
2 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()

在1处,我们添加了新属性self.battery_size,并设置其初始值(如70)。根据ElectricCar 类 创建的所有实例都将包含这个属性,但所有Car实例都不包含它。在2处,我们还添加了一个名 为describe_battery()的方法,它打印有关电瓶的信息。我们调用这个方法时,将看到一条电动 汽车特有的描述:

2016 Tesla Model S
This car has a 70-kWh battery.

对于ElectricCar类的特殊化程度没有任何限制

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

。模拟电动汽车时,你可以根据所需的准确 程度添加任意数量的属性和方法。如果一个属性或方法是任何汽车都有的,而不是电动汽车特有 的,就应将其加入到Car类而不是ElectricCar类中。这样,使用Car类的人将获得相应的功能,而 ElectricCar类只包含处理电动汽车特有属性和行为的代码。

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():--snip--
1 class Battery():"""一次模拟电动汽车电瓶的简单尝试"""
2 def __init__(self, battery_size=70):"""初始化电瓶的属性"""self.battery_size = battery_size
3 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)
4 self.battery = Battery()
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery() 

在1处,我们定义了一个名为Battery的新类,它没有继承任何类。2处的方法__init__()除 self外,还有另一个形参battery_size。这个形参是可选的:如果没有给它提供值,电瓶容量将 被设置为70。方法describe_battery()也移到了这个类中(见3)。

在ElectricCar类中,我们添加了一个名为self.battery的属性(见4)。这行代码让Python 创建一个新的Battery实例(由于没有指定尺寸,因此为默认值70),并将该实例存储在属性 self.battery中。每当方法__init__()被调用时,都将执行该操作;因此现在每个ElectricCar实 例都包含一个自动创建的Battery实例。

我们创建一辆电动汽车,并将其存储在变量my_tesla中。要描述电瓶时,需要使用电动汽车 的属性battery:

my_tesla.battery.describe_battery() 

这行代码让Python在实例my_tesla中查找属性battery,并对存储在该属性中的Battery实例 调用方法describe_battery()。 输出与我们前面看到的相同:

2016 Tesla Model S
This car has a 70-kWh battery. 

这看似做了很多额外的工作,但现在我们想多详细地描述电瓶都可以,且不会导致ElectricCar 类混乱不堪。下面再给Battery类添加一个方法,它根据电瓶容量报告汽车的续航里程:

class Car():--snip--
class Battery():--snip--
1 def get_range(self):"""打印一条消息,指出电瓶的续航里程"""if self.battery_size == 70:range = 240elif self.battery_size == 85:range = 270message = "This car can go approximately " + str(range)message += " miles on a full charge."print(message)
class ElectricCar(Car):--snip--
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
2 my_tesla.battery.get_range()

1 处新增的方法get_range()做了一些简单的分析:如果电瓶的容量为70kWh,它就将续航里 程设置为240英里;如果容量为85kWh,就将续航里程设置为270英里,然后报告这个值。为使用 这个方法,我们也通过汽车的属性battery来调用它(见2)。 输出指出了汽车的续航里程(这取决于电瓶的容量):

2016 Tesla Model S
This car has a 70-kWh battery.
This car can go approximately 240 miles on a full charge. 

9.3.6 模拟实物

模拟较复杂的物件(如电动汽车)时,需要解决一些有趣的问题。续航里程是电瓶的属性还 是汽车的属性呢?如果我们只需描述一辆汽车,那么将方法get_range()放在Battery类中也许是合 适的;但如果要描述一家汽车制造商的整个产品线,也许应该将方法get_range()移到ElectricCar 类中。在这种情况下,get_range()依然根据电瓶容量来确定续航里程,但报告的是一款汽车的续 航里程。我们也可以这样做:将方法get_range()还留在Battery类中,但向它传递一个参数,如 car_model;在这种情况下,方法get_range()将根据电瓶容量和汽车型号报告续航里程。

这让你进入了程序员的另一个境界:解决上述问题时,你从较高的逻辑层面(而不是语法层 面)考虑;你考虑的不是Python,而是如何使用代码来表示实物。到达这种境界后,你经常会发 现,现实世界的建模方法并没有对错之分。有些方法的效率更高,但要找出效率最高的表示法,需要经过一定的实践。只要代码像你希望的那样运行,就说明你做得很好!即便你发现自己不得 不多次尝试使用不同的方法来重写类,也不必气馁;要编写出高效、准确的代码,都得经过这样 的过程。

9.4 导入类

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

9.4.1 导入单个类

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

car.py
1 """一个可用于表示汽车的类"""
class Car():"""一次模拟汽车的简单尝试"""def __init__(self, make, model, year):"""初始化描述汽车的属性"""self.make = makeself.model = modelself.year = yearself.odometer_reading = 0def get_descriptive_name(self):"""返回整洁的描述性名称"""long_name = str(self.year) + ' ' + self.make + ' ' + self.modelreturn 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 = mileageelse:print("You can't roll back an odometer!")def increment_odometer(self, miles):"""将里程表读数增加指定的量"""self.odometer_reading += miles

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

my_car.py
1 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() 

1处的import语句让Python打开模块car,并导入其中的Car类。这样我们就可以使用Car类了, 就像它是在这个文件中定义的一样。输出与我们在前面看到的一样:

2016 Audi A4
This car has 23 miles on it. 

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


关于“Python”的核心知识点整理大全12-CSDN博客

往期快速传送门👆(在文章最后):

感谢大家的支持!欢迎订阅收藏!专栏将持续更新!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/223447.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

overleaf 加载pdf格式的矢量图时,visio 图片保存为pdf格式,如何确保pdf页面大小和图片一致

Overleaf支持多种矢量图形格式,其中一些常见的包括: PDF(Portable Document Format): PDF是一种常见的矢量图形格式,Overleaf可以直接加载和显示PDF文件。许多绘图工具和LaTeX生成的图形都可以导出为PDF格式…

算法的四大思想之一:回溯思想

回溯是最重要的算法思想之一,主要解决一些暴力枚举也搞不定的问题(组合、子集、分割、排列、棋盘等等)。性能并不高,但是那些暴力枚举都无法ko的问题能解出来就可以了🤣。 一、回溯思想 定义 是一个种基于深度优先搜…

免担心!如果你的处理器不支持TPM 2.0,配置一下就可以安装Windows 11了

这篇文章解释了如何使用Windows注册表编辑器将你的电脑设置为Windows 11,即使你没有支持TPM 2.0的处理器。 如何在不支持的处理器中安装Windows 11 要使你的电脑即使有不受支持的处理器也能安装Windows 11,你需要对Windows注册表进行一些更改。这并不像看上去那么复杂,但也…

YOLOv8改进 | 2023Neck篇 | 利用RepGFPN改进特征融合层(附yaml文件+添加教程)

一、本文介绍 本文给大家带来的改进机制是Damo-YOLO的RepGFPN(重参数化泛化特征金字塔网络),利用其优化YOLOv8的Neck部分,可以在不影响计算量的同时大幅度涨点(亲测在小目标和大目标检测的数据集上效果均表现良好涨点…

Redis对象——内存回收,对象共享和空转时长

一. 内存回收 因为C语言不具备内存回收功能,所以Redis在自己的对象系统中构建了一个引用计数技术实现内存回收机制。通过这一机制,程序可以通过跟踪对象的引用计数信息,在适当的时候自动释放对象并进行内存回收。 内每一个对象的引用计数信息…

平台工程与 DevOps 和 SRE 有何不同?

在现代软件开发和运营的动态领域中 ,平台工程、DevOps 和站点可靠性工程 (SRE) 等术语 经常使用,有时可以互换使用,这常常会导致进入或浏览这些领域的专业人员感到困惑。了解这些概念之间的细微差别对于努力构建强大且可扩展的系统的组织至关…

国产Apple Find My「查找」认证芯片-伦茨科技ST17H6x芯片

深圳市伦茨科技有限公司(以下简称“伦茨科技”)发布ST17H6x Soc平台。成为继Nordic之后全球第二家取得Apple Find My「查找」认证的芯片厂家,该平台提供可通过Apple Find My认证的Apple查找(Find My)功能集成解决方案。…

连连看游戏

连通块记忆性递归的综合运用 这里x,y的设置反我平常的习惯,搞得我有点晕 实际上可以一输入就交换x,y的数据的 如果设置y1为全局变量的话会warning: warning: built-in function y1 declared as non-function 所以我改成p和q了…

一些好用的VSCode扩展

可以在扩展这里直接搜索需要的扩展,点击安装即可。 1.Chinese 中文扩展,就是说虽然咱们懂点英语,但还是中文看着方便 2.Auto Rename Tag 当你重命名一个HTML 标签时,会自动重命名与他配对的HTML 标签 当你选择h4这个标签时&…

系列三、DDL

一、DDL 1.1、概述 DDL是英文单词Data Definition Language的缩写,中文意思为数据定义语言,是用来定义数据库对象(数据库,表,字段)的。 1.2、数据库操作 1.2.1、查询所有数据库 show databases; 1.2.2、创建数据库 # 语法 cre…

云原生基础入门概念

文章目录 云原生的概念云原生的关键技术为何选择云原生?云原生的实际应用 当谈及现代软件开发和IT基础架构时,云原生成为了一个备受关注的话题。它代表了一种软件架构和开发方法,旨在充分利用云计算环境的优势,以提高应用程序的可…

【AI美图】第02期效果图,AI人工智能全自动绘画,美图欣赏

今天给大家献上一组最新提示词 参照图生成图像 依据参照图生成新的图像需要掌握一些技巧,以下是一些可能有用的技巧: 观察参照图:在开始生成新图像之前,仔细观察参照图是非常重要的。你需要了解图像的布局、颜色、线条、细节等…

新一代“垫图”神器,IP-Adapter的完整应用解读

导读 不用训练lora,一张图就能实现风格迁移,还支持多图多特征提取,同时强大的拓展能力还可接入动态prompt矩阵、controlnet等等,这就是IP-Adapter,一种全新的“垫图”方式,让你的AIGC之旅更加高效轻松。 …

智慧工地源码(微服务+Java+Springcloud+Vue+MySQL)

智慧工地系统是依托物联网、互联网、AI、可视化建立的大数据管理平台,是一种全新的管理模式,能够实现劳务管理、安全施工、绿色施工的智能化和互联网化。围绕施工现场管理的人、机、料、法、环五大维度,以及施工过程管理的进度、质量、安全三…

Python Socket编程

Python Socket编程 文章目录 Python Socket编程1. 弄懂HTTP、Socket、TCP这几个概念五层网络模型 2. client和server实现通信Socket编程模式指南代码实现 3. socket实现聊天和多用户连接4. socket模拟http请求5. socket使用I/O多路复用模式模拟http请求 1. 弄懂HTTP、Socket、T…

51单片机的外部中断的以及相关寄存器的讲解

中断系统 本文主要涉及8051单片机的中断系统的讲解与使用 其中包括中断相关寄存器的介绍与使用以及外部中断初始化的代码分析。 文章目录 中断系统一、 中断的介绍二、 中断结构及相关寄存器2.1 中断源 2.2 中断请求控制器2.2.1 TCON寄存器2.2.2 SCON寄存器2.2.3 中断允许寄存器…

【每日一题】【12.15】2415.反转二叉树的奇数层

🔥博客主页: A_SHOWY🎥系列专栏:力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 2415. 反转二叉树的奇数层https://leetcode.cn/problems/reverse-odd-levels-of-binary-tree/ 今天终于碰到了一个mid题目&#x…

数据库常用分库分表方案

为什么需要分库分表 分库分表是因应数据库处理大规模数据时所面临的挑战而出现的解决方案. // 提高性能 单个数据库在数据量增加时容易出现性能瓶颈。分库分表可以减轻单个数据库的负担,提高系统的读写性能和响应速度. // 提高并发能力 大量用户同时访问数据库可能…

N-Channel Trench Power MOSFET FMA30H150SL

FMA30H150SL N-Channel Trench Power MOSFET FMA30H150SL Application :  LCD TV  Notebook  Elevator  Inductive heating  Power tools  Broadband FMA30H150SL Features :  30V,150A  RDS(ON)2.4mΩ (Typ.) VGS 10V …

若依 ruoyi-vue3 集成aj-captcha实现滑块、文字点选验证码

目录 0. 前言0.1 说明 1. 后端部分1.1 添加依赖1.2. 修改 application.yml1.3. 新增 CaptchaRedisService 类1.4. 添加必须文件1.5. 移除不需要的类1.6. 修改登录方法1.7. 新增验证码开关获取接口1.8. 允许匿名访问 2. 前端部分(Vue3)2.1. 新增依赖 cryp…