python之面向对象编程

2023-11-04

最近阅读到了一篇关于面向对象编程和面向过程编程解释说明的文章,觉得写的通俗易懂。文章链接如下:
漫画:如何通俗易懂地解释面向对象思想?
但是该文章举的例子是用Java,故在此我按照我的理解,针对python,梳理一下面向对象编程。

一、面向对象编程背景和定义

维基百科:面向对象程序设计

1.背景

面向对象程序设计的雏形,早在1960年代的Simula语言中即可发现,当时的程序设计领域正面临着一种危机:在软硬件环境逐渐复杂的情况下,软件如何得到良好的维护?面向对象程序设计在某种程度上通过强调可重复性解决了这一问题。

2.定义

面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的编程典范,同时也是一种程序开发的抽象方针。它可能包含数据、特性、代码与方法。对象则指的是类(class)的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象。

从维基百科的定义可以看出,面向对象编程的对象在Python中指的是类(class)的实例。

二、面向对象编程和面向过程编程

看上面对于面向对象编程的定义,感觉对面向对象编程还是很模糊。下面根据参考文章中的例子,对比面向过程编程来对面向对象编程进行进一步说明。

情景说明
1.某商店需要用代码完成输入客人购买商品的数量和单价,返回客人购买商品的总价格。
由于代码比较简单,面向对象和面向过程编程得到的代码一样,如下。

class Bill(object):
    
    def __init__(self, unit, number):
        self.unit = unit
        self.number = number
        self.price = self.unit * self.number
        
    def getPrice(self):
        return self.price 


if __name__ == '__main__':
    
    unit = 10
    number = 2
    
    demo = Bill(unit, number)
    print(demo.getPrice())

从这个情境中难以看出面向对象和面向过程的区别。别急,接下来在1的基础上增加需求。

2.该商店七夕大酬宾,七夕节当天所有商品均打77折
面向过程编程结果如下:

class Bill(object):
    
    def __init__(self, unit, number, todayIsLoversDay):
        self.unit = unit
        self.number = number
        self.price = self.unit * self.number
        self.todayIsLoversDay = todayIsLoversDay
        
    def getPrice(self):
        if self.todayIsLoversDay:
            return self.price * 0.77
        return price 


if __name__ == '__main__':
    
    unit = 10
    number = 2
    todayIsLoversDay = True
    
    demo = Bill(unit, number, todayIsLoversDay)
    print(demo.getPrice())

因为面向对象编程主要关注于对象,故新建一个类,但是因为新的类需要用到Bill类中的unit、number、price,故要继承Bill类。
面向对象编程如下:

class Bill(object):
    
    def __init__(self, unit, number):
        self.unit = unit
        self.number = number
        self.price = self.unit * self.number
        
    def getPrice(self):
        return self.price 
    
class LoversDayBill(Bill):
    
    def __init__(self, unit, number):
        super(LoversDayBill, self).__init__(unit, number)       
    
    def discount(self):
        return self.price * 0.77
    


if __name__ == '__main__':
    
    unit = 10
    number = 2
    
    demo = LoversDayBill(unit, number)
    print(demo.discount())

从这个场景不难看出,面向对象对于代码的改动较多,面向过程编程只是添加了一个if语句,而面向对象编程则直接写了一个新的类,只不过这个类是继承Bill类。
那么是不是面向对象编程就比面向过程编程复杂呢?我们再在情景2的基础上增加需求。

3.增加需求,中秋节满399减100,国庆节100元以内的有1/10概率免单。

面向过程编程一如既往在getPrice中添加if语句,但此时已经显得比较复杂了,无论是新增或删除代码,在这个过长的类里做修改都是件不太愉快的事。为了在一个很长的函数中找到需要修改的位置,「面向过程」使得老过不得不浏览大量与修改无关的代码,小心翼翼地修改后,又要反复确认不会影响到类的其他部分。

面向对象编程和情景2一样,因为都是对价格进行处理,故这次新写了两个类分别处理中秋节和国庆节,这两个类都继承了Bill类。

应对新需求时,无需改变经测试通过的既有的类。它良好的灵活性和扩展性仿佛天上就是用来适应变化的。每个支付方式相互独立,假设若某一天不再需要时,将对应的类删除即可。

4.修改需求,情景2中情人节活动更改为凡是到本店来购物的情侣满99元及以上的订单随机附赠精美礼品一份【鲜花、巧克力、9.9元优惠卷】,之前打77着的活动也修改为仅限情侣参加。
这次面向过程编程明显要在getPrice函数中的关于情人节的if语句进行修改,而面向对象编程则只需要找到LoversDayBill这个类,修改这个类即可。

从这4个场景不难看出面向对象和面向过程的编程思想是如何实现的。面向过程编程始终在修改Bill类,而面向对象编程始终是添加新的类(继承Bill类)

面向对象的编程方式使得每一个类都只做一件事。面向过程会让一个类越来越全能,就像一个管家一样做了所有的事。 而面向对象像是雇佣了一群职员,每个人做一件小事,各司其职,最终合作共赢!

三、引申阅读

《大话设计模式》中大鸟给小菜讲的故事非常经典:

“话说三国时期,曹操带领百万大军攻打东吴,大军在长江赤壁驻扎,军船连成一片,眼看就要灭掉东吴,统一天下,曹操大悦,于是大宴众文武,在酒席间,曹操诗性大发,不觉吟道:‘喝酒唱歌,人生真爽……’众文武齐呼:‘丞相好诗!’于是一臣子速命印刷工匠刻版印刷,以便流传天下。”

“样张出来给曹操一看,曹操感觉不妥,说道:‘喝与唱,此话过俗,应改为‘对酒当歌’较好!’于是此臣就命工匠重新来过。工匠眼看连夜刻版之工,彻底白费,心中叫苦不迭。只得照办。”

“样张再次出来请曹操过目,曹操细细一品,觉得还是不好,说:‘人生真爽‘太过直接,应改问语才够意境,因此应改为‘对酒当歌,人生几何……’当臣子转告工匠之时,工匠晕倒……”

大鸟:“小菜你说,这里面问题出在哪里?”

小菜:“是不是因为三国时期活字印刷还未发明,所以要改字的时候,就必须要整个刻板全部重新刻。”

大鸟:“说得好!如果是有了活字印刷,则只需更改四个字就可,其余工作都未白做。岂不妙哉。

一、要改,只需更改要改之字,此为可维护

二、这些字并非用完这次就无用,完全可以在后来的印刷中重复使用,此乃可复用

三、此诗若要加字,只需另刻字加入即可,这是可扩展

四、字的排列其实可能是竖排可能是横排,此时只需将活字移动就可做到满足排列需求,此是灵活性好。”

“而在活字印刷术出现之前,上面的四种特性都无法满足,要修改,必须重刻,要加字,必须重刻,要重新排列,必须重刻,印完这本书后,此版已无任何可再利用价值。”

小菜:“是的,小时候我一直奇怪,为何火药、指南针、造纸术都是从无到有,从未知到发现的伟大发明,而活字印刷仅仅是从刻版印刷到活字印刷的一次技术上的进步,为何不是评印刷术为四大发明之一呢?原来活字印刷是思想的成功,面向对象的胜利。”

四、面向对象的基本特征

面向对象的有三个基本特征:封装、继承、多态。
封装: 我的理解就是把一个东西用类表示,就像Bill类
继承: 我的理解就是子类有一部分父类以及写好,直接把父类拿来用就像。就像loversDayBill类中的price。
多态: 我的理解就是多个子类运行用相同的方法名。

关于python类的继承、多态请参考:
一文看懂Python面向对象编程
什么是多态,Python多态及用法详解

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python之面向对象编程 的相关文章

  • 如何使用python登录页面,该页面需要服务器在第一次请求时响应会话ID?

    我正在编写一个脚本来登录某个网页 我使用 request 和 request session 模块来实现此目的 在使用登录参数的第一个请求时 服务器响应一个会话 ID 如何设置该会话 ID 以进一步登录到同一页面 url some url
  • Pytorch - 推断线性层 in_features

    我正在构建一个玩具模型来获取一些图像并进行分类 我的模型看起来像 conv2d gt pool gt conv2d gt linear gt linear 我的问题是 当我们创建模型时 我们必须计算第一个线性层的大小in features基
  • Keras model.summary() 结果 - 了解参数数量

    我有一个简单的神经网络模型 用于使用 Keras Theano 后端 从用 python 编写的 28x28px 图像中检测手写数字 model0 Sequential number of epochs to train for nb ep
  • 使用 glGetFloatv 检索 pyglet 中的模型视图矩阵

    我正在使用 pyglet 在 python 中进行 3D 可视化 并且需要检索模型视图和投影矩阵来进行一些选择 我使用以下方式定义我的窗口 from pyglet gl import from pyglet window import wi
  • 在 Python 中同时插入行

    我正在尝试对我的代码进行矢量化 但遇到了障碍 我有 nxd x 值数组 x1 xn 其中每一行 x1 有很多点 x11 x1d nxd y 值数组 y1 y2 y3 其中每一行 y1 有很多点 y11 y1d x 值的 nx1 数组 x 1
  • Json.dump 失败并显示“必须是 unicode,而不是 str”TypeError

    我有一个 json 文件 其中恰好有大量中文和日文 以及其他语言 字符 我将其加载到我的 python 2 7 脚本中使用io open如下 with io open multiIdName json encoding utf 8 as j
  • Python,将字典存储在数据库中

    在数据库中存储和检索 python 字典的最佳方法是什么 如果您对使用传统 SQL 数据库 例如 MySQL 不是特别感兴趣 您可以研究非结构化文档数据库 其中文档自然映射到 python 字典 例如MongoDB http www mon
  • 将 2D Panda 的 DataFrame 列表转换为 3D DataFrame

    我正在尝试创建一个将标签值保存到 2D DataFrame 的 Pandas DataFrame 这是我到目前为止所做的 我正在使用读取 csv 文件pd read csv并将它们附加到列表中 出于这个问题的目的 让我们考虑以下代码 imp
  • 使用pip安装pylibmc时出错

    您好 当我尝试使用 pip 在 OSX Lion 上安装 pylibmc 时 出现以下错误 pylibmcmodule h 42 10 fatal error libmemcached memcached h file not found
  • 使用 Python 将阿拉伯语或任何从右到左书写系统的字符串打印到 Linux 终端

    非常简单的例子是 city print city 我期望输出是 但实际上输出是相反的字符串 字母看起来有点不同 因为它们有开始 中间和结束形式 我无法将其粘贴到此处 因为复制粘贴会再次更正字符串的顺序 如何在 Linux 终端上正确打印阿拉
  • self.__dict__.update(**kwargs) 的风格是好是坏?

    在 Python 中 假设我有一些类 Circle 它继承自 Shape Shape 需要 x 和 y 坐标 此外 Circle 需要半径 我希望能够通过执行类似的操作来初始化 Circle c Circle x 1 y 5 r 3 Cir
  • 如何使用appium自动化Android手机后退按钮

    我正在使用 Appium python 客户端库 对 Android 上的混合移动应用程序进行测试自动化 我无法找到任何方法来自动化或创建手势以使用 电话后退 按钮返回到应用程序的上一页 有没有可以使用的驱动函数 我尝试了 self dri
  • 模拟类:Mock() 还是 patch()?

    我在用mock http www voidspace org uk python mock index html使用Python 想知道这两种方法中哪一种更好 阅读 更Pythonic 方法一 只需创建一个模拟对象并使用它 代码如下 def
  • 如何使用 selenium 获取 javascript 结果?

    我有以下代码 from selenium import selenium selenium selenium localhost 4444 chrome http some site com selenium start sel selen
  • Python itertools groupby 中令人不安的奇怪行为/错误?

    我在用itertools groupby解析一个短的制表符分隔的文本文件 文本文件有几列 我想做的就是对具有特定值的所有条目进行分组x在特定的列中 下面的代码对名为的列执行此操作name2 寻找变量中的值x 我尝试使用以下方法来做到这一点c
  • pandas-更改重采样时间序列的开始和结束日期

    我有一个时间序列 我将其重新采样到这个数据框中df 我的数据是从6月6日到6月28日 它希望将数据从6月1日延长到6月30日 计数列仅在较长时间内具有 0 值 而我的实际值是从 6 日到 28 日 Out 123 count Timesta
  • Python 包安装:pip 与 yum,还是两者一起安装?

    我刚刚开始管理 Hadoop 集群 我们使用 Bright Cluster Manager 直至操作系统级别 CentOS 7 1 然后使用 Ambari 以及适用于 Hadoop 的 Hortonworks HDP 2 3 我不断收到安装
  • 对 Python 列表元素进行分组

    我有一个 python 列表 如下所示 my list 25 1 0 65 25 3 0 63 25 2 0 62 50 3 0 65 50 2 0 63 50 1 0 62 我想根据以下规则对它们进行排序 1 gt 0 65 0 62 l
  • python 相当于 sed

    有没有一种方法 无需双循环即可完成以下 sed 命令的操作 Input Time Banana spinach turkey sed i Banana s Toothpaste file Output Time BananaToothpas
  • 混合两个列表的Pythonic方法[重复]

    这个问题在这里已经有答案了 我有两个长度为 n 和 n 1 的列表 a 1 a 2 a n b 1 b 2 b n 1 我想要一个函数作为结果给出一个列表 其中包含两个中的替代元素 即 b 1 a 1 b n a n b n 1 以下方法有

随机推荐

  • 使用 freeMarker 生成 word 遇到的问题

    1 循环集合生成表格后 生成的表格连在一起 解决方法 使用xml中的分页符
  • 解决方案:AttributeError: ‘NoneType‘ object has no attribute ‘write‘

    目前因为在制造型企业 python的服务使用flask开发 打包部署的方式是使用pyinstaller打包成exe程序 然后部署 但是使用pip安装了版本是5 7 0的以后 打包部署启动的时候就报错如下 Traceback most rec
  • C++ QT 上传图片至mysql数据库

    以下是一个简单的C QT上传图片至MySQL数据库的代码示例 include
  • Android.mk 文件语法详解

    0 Android mk简介 Android mk文件用来告知NDK Build 系统关于Source的信息 Android mk将是GNU Makefile的一部分 且将被Build System解析一次或多次 所以 请尽量少的在Andr
  • linux下quartus ii 安装心酸之路,解决modelsim-altera无法进行RTL仿真的问题

    这是我第一次认真的记录一下我安装的quartusii的心酸的过程 现在我只把我不断尝试最终成功的经历记录如下 一开始先下载安装包 我下载的是官网的prime版本 https download altera com akdlm softwar
  • 压电阀控制器设计—思考总结篇

    此篇主要是总结一下这一年左右时间设计的压电阀控制器心得 以及未来压电阀发展趋势的讨论 控制设计心得 最初接手设计压电阀工作作为硕士的毕业课题 也很紧张忐忑 因为之前基本没怎么接触这个领域 掌握的设计资源也基本为无 所以基本是一个从零开始的造
  • Flutter 图片加载

    内容简介 Flutter图片加载方式 网络图片加载源码流程跟踪 特别提到的优化点 本篇文章你将获得 1 Flutter 图片加载方式 2 Flutter 图片加载源码实现流程 3 Flutter 图片加载优化点有什么 Flutter Ima
  • xmanager - xstart - The X11 forwarding request was rejected

    安装xmanager 启动xstart的时候报错 The X11 forwarding request was rejected 查询了下 ssh的设置参数都正常 再次重装了下桌面环境 就恢复了 解决办法 在linux 机器上执行语句 yu
  • eclipse开发运行C++程序(新手入门详细教程)

    eclipse有好几种IDE 先说两种 一种是eclipse IDE for java 一种是eclipse IDE for c eclipse IDE for java下载地址 https www eclipse org download
  • 安装mlxtend_利用mlxtend进行数据关联分析

    guan 大数据挖掘最深入人心的一个故事应该是 啤酒与尿布 这个规律就是用关联分析发现的 今天我们就来点关联分析 刚刚学到的 现学现分享 下面假设是某超市的交易记录 我编造的 基本概念 我们在关联分析之前先了解几个基本概念 找出频繁一起出现
  • 【洛谷 P1328】[NOIP2014 提高组] 生活大爆炸版石头剪刀布 题解(模拟+向量)

    NOIP2014 提高组 生活大爆炸版石头剪刀布 题目描述 石头剪刀布是常见的猜拳游戏 石头胜剪刀 剪刀胜布 布胜石头 如果两个人出拳一样 则不分胜负 在 生活大爆炸 第二季第 8 集中出现了一种石头剪刀布的升级版游戏 升级版游戏在传统的石
  • [Flex]在TextArea中嵌入圖像

    TextArea的htmlText支持多種html標簽 如 a b br font img 等 這裏使用 img 標簽來將圖片嵌入到TextArea中 img 標簽可用于嵌入JPEG GIF PNG及SWF等媒體文件到文本框中 文本會自動分
  • pads更新原理图后,pcb文件出现* Part nameXXX not found解决方法

    方法 MAX Layers
  • 思科 BroadWorks 受严重的认证绕过漏洞影响

    聚焦源代码安全 网罗国内外最新资讯 编译 代码卫士 思科BroadWorks Application Delivery Plaftform 和BroadWorks Xtended Services Platform 受一个严重漏洞 CVE
  • Anacoda3中成功配置Tesseract-OCR实现OCR文字识别超详细教程!!(win7、win10)

    Anacoda3中成功配置Tesseract OCR Tesseract OCR简介 安装及配置环境步骤 1 在Anaconda虚拟环境中安装pytesseract第三方库 2 下载tesseract ocr安装包并安装 3 环境配置 检验
  • 图像知识 太经典 膜拜

    图像知识 图形图像 图形设备和系统 图形文件的显示 图形文件的格式 WINDOWS编程基础 WINDOWS图像编程 动画技术 三维世界 图形图像 传统的电脑只能处理文字 数字 最多是简单的图形 近年来 随着电脑硬件技术的飞速发展和更新 使得
  • 三冲IPO的思派健康如何承载腾讯的互联网医疗梦?

    腾讯在互联网医疗领域的 大将 思派健康10月27日向港交所主板递交第三次上市申请 在2021年8月6日和2022年2月25日两次 折戟 港交所后 此次能否如愿以偿仍未可知 我国当前正步入老龄化社会 慢性病人口增加 市场对医疗健康方面的需求不
  • 十秒带你了解python程序结构

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 Python中有三种程序结构 顺序结构 分支结构 循环结构 1 顺序结构 pyth
  • 【分布式】红包秒杀系统、高并发安全分布式锁

    分布式 内容管理 业务Intro 业务模块划分 数据库表设计 开发流程 红包金额随机生成算法 Monte Carlo 方法 发红包模块 EnableAsync 多线程异步 抢红包模块 并发测试 Jmeter压力测试高并发下抢红包 并发安全问
  • python之面向对象编程

    最近阅读到了一篇关于面向对象编程和面向过程编程解释说明的文章 觉得写的通俗易懂 文章链接如下 漫画 如何通俗易懂地解释面向对象思想 但是该文章举的例子是用Java 故在此我按照我的理解 针对python 梳理一下面向对象编程 一 面向对象编