python数据结构之面向对象
作者:柳小葱 发布时间:2021-04-09 08:02:06
前文学习:
python数据结构:数据类型.
python数据结构输入输出及控制和异常.
今天我们来学习面向对象编程,面向对象这种编程方式非常重要,我们以后学习到的栈、队列、链表都是通过面向对象的方式实现的。
1. 面向对象编程
定义:面向对象是按照人们客观世界的系统思维方式,采用基于对象(实体)的概念建立模型 ,模拟客观世界分析,设计,实现软件的办法。通过面向对象的理念使计算机软件系统能与现实世界中的系统的一一对应。
听到这很多同学应该会很蒙,我解释一下几个关键词的概念:
对象:一切事物都可以是对象,更准确的说,对象是一个实体,用一组可识别的特征和行为来标识,可以说对象不同的地方就是具有不同的特征与行为。
类:是具有相同属性和功能的对象抽象集合
实例:就是创建具体对象的过程
举一个面向对象的例子:我们需要造一辆车,我们可能并不需要知道车的原理,我们只需要找到车的轮子,车的车架,车的发动机,然后将它们拼装在一起即可。
在前面我们已经使用了一些內建的类来展示数据和控制结构的例子。面向对象编程语言最强大的一项特性是允许程序员(问题求解者) 创建全新的类来对求解问题所需的数据进行建模。
我们之前使用了抽象数据类型来对数据对象的状态及行为进行逻辑描述。通过构建能实现抽象数据类型的类,可以利用抽象过程,同时为真正在程序中运用抽象提供必要的细节。每当需要实现抽象数据类型时,就可以创建新类。
2. 构建类
我们来构建一个分数类fraction类:
你这不能用除法?其实是可以,但是除法的方式python已经有自己的类了,我这里需要自己创建一个分数类。
所有类都应该首先提供构造方法。构造方法定义了数据对象的创建方式。要创建 Fraction
类的实例,必须调用构造方法,要创建一个 Fraction
对象,需要提供分子和分母两部分数据。
class fraction: #定义一个类
def __init__(self,top,bottom):#定义构造方法 __init__
self.num=top
self.den=bottom
这里解释一下,self 是一个总是指向对象本身的特殊参数,它必须是第一 个形式参数。然而,在调用方法时,从来不需要提供相应的实际参数。如前所述,分数需要分子与分母两部分状态数据。构造方法中的 self.num
定义了 Fraction 对象有一个叫作 num 的内部数据对象作为其状态的一部分。同理,self.den
定义了分母。这两个实际参数的值在初始时,赋给了状态,使得新创建的 Fraction
对象能够知道其初始值。
class fraction: #定义一个类
def __init__(self,top,bottom):#定义构造方法 __init__
self.num=top
self.den=bottom
myfraction = fraction(3,5)#使用类创建一个对象。
我们可以用下面这个图来描述,我们构造类一个类,然后通过类创建了一个对象。
一般情况下,我们定义了一个类,里面会有这个类的一些方法,例如,我要查看这个分数对象的样子,我要计算这中类型的分数,等等方法,这些都需要我们去定义。
class fraction: #定义一个类
def __init__(self,top,bottom):#定义构造方法 __init__
self.num=top
self.den=bottom
def show(self): #定义输出方法
print(self.num,"/",self.den)
def add(self,otherf): #定义分数加法
bot=otherf.den * self.den
top=self.num * otherf.den +self.den * otherf.num
print(top,"/",bot)
#定义两个分数
myfraction=fraction(9,16)
a=fraction(1,16)
#试试加法
myfraction.add(a)
结果如下:
这里我们放上我们写好的分数类定义方法。
class Fraction:
def __init__(self, top, bottom):
self.num = top
self.den = bottom
def __str__(self):
return str(self.num) + "/" + str(self.den)
def show(self):
print(self.num, "/", self.den)
def __add__(self, otherfraction): #加法 ,可以用+
newnum = self.num * otherfraction.den + self.den * otherfraction.num
newden = self.den * otherfraction.den
common = gcd(newnum, newden)
return Fraction(newnum//common, newden//common)
def __eq__(self, other): #深相等,值相等就相等
firstnum = self.num * other.den
secondnum = other.num * self.den
return firstnum == secondnum
3. 继承
继承是面向对象编程的一个重要特征:使一个类与另一个类相关联,就像人们相互联系一样。孩子从父母那里继承了特征,python
的子类可以从父类那继承数据和行为,父类也称为超类。
就拿我们前面学习过的基础数据结构举例。
列表、字符串和元组都是有序集合。它们都继承了共同的数据组织和操作。不过,根据数据是否同类以及集合是否可修改,它们彼此又有区别。子类从父类继承共同的特征,但是通过额外的特征彼此区分。
3.1 继承案例
我们这里通过一个小的案例来实现继承的案例,我们来构建一个模拟程序,用于模拟数字电路。逻辑门是这个模拟程序的基本构造单元,它们代表其输入和输出之间的布尔代数关系。
通过不同的模式将这些逻辑门组合起来并提供一系列输入值,可以构建具有逻辑功能的电 路。图 1-10 展示了一个包含两个与门、一个或门和一个非门的电路。两个与门的输出直接作为 输入传给或门,然后其输出又输入给非门。如果在 4 个输入处(每个与门有两个输入)提供一系列值,那么非门就会输出结果。
为了实现电路,首先需要构建逻辑门的表示。可以轻松地将逻辑门组织成类的继承层次结构, 如图所示。顶部的 LogicGate
类代表逻辑门的通用特性:逻辑门的标签和一个输出。下面 一层子类将逻辑门分成两种:有一个输入的逻辑门和有两个输入的逻辑门。再往下,就是具体的逻辑门。
首先定义父类LogicGate
class LogicGate:
def __init__(self, n):#构造函数,label代表的是自己的名字
self.label = n
self.output = None
def getLabel(self):#输出名字的函数
return self.label
def getOutput(self):#输出的结果
self.output = self.performGateLogic()
return self.output
目前还不用实现 performGateLogic
函数。原因在于,我们不知道每一种逻辑门将如何进 行自己的逻辑运算。这些细节会交由继承层次结构中的每一个逻辑门来实现。这是一种在面向对象编程中非常强大的思想——我们创建了一个方法,而其代码还不存在。参数 self 是指向实际调用方法的逻辑门对象的引用。任何添加到继承层次结构中的新逻辑门都仅需要实现之后会被调用的 performGateLogic
函数。一旦实现完成,逻辑门就可以提供运算结果。扩展已有的继承层次结构并提供使用新类所需的特定函数,这种能力对于重用代码来说非常重要。
定义子类BinaryGate类、UnaryGate类
两个类中的构造方法首先使用 super
函数 来调用其父类的构造方法。当创建 BinaryGate
类的实例时,首先要初始化所有从LogicGate
中继承来的数据项,在这里就是逻辑门的标签。接着,构造方法添加两个输入(pinA 和 pinB)。 这是在构建类继承层次结构时常用的模式。子类的构造方法需要先调用父类的构造方法,然后再 初始化自己独有的数据。
BinaryGate类主要是与门和或门(有两个输入)
class BinaryGate(LogicGate):
def __init__(self, n):
super().__init__(n)#继承父类的构造方法
self.pinA = None #添加自己的参数
self.pinB = None
def getPinA(self):#自己的方法
return int(input("Enter Pin A input for gate "+self.getLabel() + "-->"))
def getPinB(self):#自己的方法
return int(input("Enter Pin B input for gate "+self.getLabel() + "-->"))
UnaryGate类主要是非门(只有一个输入)。
class UnaryGate(LogicGate):
def __init__(self, n):
super().__init__(n)#继承父类的构造方法
self.pin = None#添加自己的参数
def getPin(self):#自己的方法
return int(input("Enter Pin input for gate " + self.getLabel() + "-->"))
构造孙类(与门、或门、非门)
与门 AndGate类
#构造与门
class AndGate(BinaryGate):
def __init__(self, n):
super().__init__(n)#继承父类方法
def performGateLogic(self):#自己的运算逻辑
a = self.getPinA()
b = self.getPinB()
if a==1 and b==1:
return 1
else:
return 0
或门 OrGate
class OrGate(BinaryGate):
def __init__(self, n):
super().__init__(n)#继承父类方法
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a==1 or b==1:
return 1
else:
return 0
非门 NotGate
class NotGate(UnaryGate):
def __init__(self, n):
super().__init__(n)
def performGateLogic(self):
a = self.getPin()
if a==1:
return 0
else:
return 1
测试一下结果:
与门
或门
非门
参考资料:
《python数据结构与算法》
《大话数据结构》
来源:https://blog.csdn.net/weixin_48077303/article/details/119170555


猜你喜欢
- 什么是事务?事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。数据库事务通常包含了一个序列的对数据库的读/写操作
- show.php源代码: <? if ($action=="cp"){ echo"<div ali
- 题记:django如果要并和原有的数据库,那么就需要把现有数据库的表写入model.py中。一,在setting.py中配置好连接数据库的参
- Vue中keep-alive的使用我总结的有两种方式应用:首先简述一下keep-alive的作用,kee-alive可以缓存不活动的的组件。
- 1. 简介在 Go 语言中,new 和 make 是用于创建对象的两个内建函数,它们的使用方式和作用有所不同。正确理解 new 和 make
- 排序,是许多编程语言中经常出现的问题。同样的,在Python中,如何是实现排序呢?(以下排序都是基于列表来实现)一、使用Python内置函数
- tk在科学养猪群里问bluerust、scz是否碰上过这个Python坑,示例1:bas = [ 'ba1', 'b
- 1 介绍U-Net最初是用来对医学图像的语义分割,后来也有人将其应用于其他领域。但大多还是用来进行二分类,即将原始图像分成两个灰度级或者色度
- 我听说在ASP里,可以不用DSN来连接EXCEL,请问如何实现?确实ASP提供了替代DSN的其他方法,甚至可以在运行时建立连接看看下面的范例
- 使用cpan安装Net::SSH::Perl:cpan>install Net::SSH::Perl期间遇到了一些问题,记录在此,以备
- 当多个事务同时持有和请求同一资源上的锁而产生循环依赖的时候就产生了死锁。死锁发生在事务试图以不同的顺序锁定资源。以StockPrice表上的
- 对于Python而言代码缩进是一种语法,Python没有像其他语言一样采用{}或者begin...end分隔代码块,而是采用代码缩进和冒号来
- 雅虎的BrowserPlus在曝光了N久后终于发布了,一款类似于Google Gears的浏览器增强插件。在支持的操作系统方面,Gears明
- 总结:下载文件的方式a 标签配置 download 属性 (适用于下载一些静态资源)window.location.href (适用于下载一
- 增加异常捕获,更容易现问题的解决方向import sslimport urllib.requestfrom bs4 import Beaut
- 感谢Mr.Cool 给asp之家投递精彩的文章!站长你好,我经常光临你的站点,因为我也特别喜欢ASP写网页,你的站点上提供的代码比较适用哈,
- 下面给大家介绍Javascript removeChild()删除节点的方法,具体详情如下所示:在Javascript中,只提供了一种删除节
- 网站开发时经常需要在某个页面需要实现对大量图片的浏览,如果考虑流量的话,大可以像pconline一样每个页面只显示一张图片,让用户每看一张图
- Whoosh 是纯Python实现的全文搜索引擎,通过Whoosh可以很方便的给文档加上全文索引功能。什么是全文检索简单讲分为两块,一块是分
- 在学习asyncio之前,先理清楚同步/异步的概念:同步是指完成事务的逻辑,先执行第一个事务,如果阻塞了,会一直等待,直到这个事务完成,再执