python总结(2)

面向 对象

在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法。使用对象而非全局变量和函数的原因有多个,下面列出了使用对象的最重要的好处。

口 多态:可对不同类型的对象执行相同的操作,而这些操作就像“被施了魔法”一样能够正常运行。

口 封装:对外部隐藏有关对象工作原理的细节

口 继承:可基于通用类创建出专用类。

在很多介绍面向对象编程的资料中,都以不同于这里的顺序介绍上述概念。一般先介绍封装和继承,再使用这些概念来模拟现实世界的对象。这没什么不好,但在我看来,多态才是面向对象编程最有趣的特性。根据我的经验,这也是让大多数人感到迷惑的特性。有鉴于此,我将首先介绍多态,并力图证明仅凭这个概念就足以让你喜欢上面向对象编程。

多态

术语多态(polymorphism)源自希腊语,意思是“有多种形态”。这大致意味着即便你不知道变量指向的是哪种对象,也能够对其执行操作,且操作的行为将随对象所属的类型(类)而异。例如,假设你要为一个销售食品的电子商务网站创建在线支付系统,程序将接收来自系统另一部分(或之后设计的类似系统)的购物车。因此你只需计算总价并从信用卡扣除费用即可。

你首先想到的可能是,指定程序收到商品时必须如何表示。例如,你可能要求用元组表示收到的商品如下所示:

('SPAM'2.50)

如果你只需要描述性标签和价格,这样的表示很好,但不太灵活。假设该网站新增了拍卖服务,即不断降低商品的价格,直到有人购买为止。在这种情况下,如果能够允许用户像下面这样做就好了:将商品放入购物车并进入结算页面(你所开发系统的一部分),等到价格合适时再单击“支付”按钮。

然而,使用简单的元组表示商品无法做到这一点。要做到这一点,表示商品的对象必须在你编写的代码询问价格时通过网络检查其当前价格,也就是说不能像在元组中那样固定价格。要解决这个问题,可创建个函数。

#不要像下面这样做:def get_price(object):if isinstance(object, tuple):return object[1]else:return magic network method(object)

注意 这里使用isinstance来执行类型/类检査旨在说明:使用类型检査通常是馊主意,应尽可能避免。

前面的代码使用函数isinstance来检查object是否是元组。如果是,就返回其第二个元素,否则调用一个神奇的网络方法。

如果网络方法已就绪,问题就暂时解决了。但这种解决方案还是不太灵活。如果有位程序员很聪明,

,决定用十六进制的字符串表示价格,并将其存储在字典的’price"键下呢?没问题,你只需更新相应的函数。

#不要像下面这样做:def get price(object):if isinstance(object, tuple):return object[1]elif isinstance(object, dict):return int(object price)else:return magic network method(object)

你确定现在考虑到了所有的可能性吗?假设有人决定添加一种新字典,并在其中将价格存储在另一个键下,你该如何办呢?当然,可再次更新get price,但这种应对之策能在多长时间内有效呢?每当有人以不同的方式实现对象时,你都需要重新实现你的模块。如果你将该模块卖给了别人,转而从事其他项目的开发客户该如何办呢?显然,这种实现不同行为的方式既不灵活也不切实际。

那么该如何做呢?让对象自己去处理这种操作。这好像没什么大不了,但仔细想想将发现,这样事情将简单得多:每种新对象都能够获取或计算其价格并返回结果,而你只需向它们询问价格即可。这正是多态(从某种程度上说还有封装)的用武之地。

多态和方法

你收到一个对象,却根本不知道它是如何实现的–它可能是众多“形态”中的任何一种。你只知道可以询问其价格,但这就够了。至于询问价格的方式,你应该很熟悉。

>>>object.get_price()2.5

像这样与对象属性相关联的函数称为方法。你在本书前面见过这样的函数:字符串、列表和字典的方法。

>>>'abc’.count('a' )>>>[1, 2,'a’]. count(' a )

如果有一个变量x,你无需知道它是字符串还是列表就能调用方法count:只要你向这个方法提供一个字符作为参数,它就能正常运行。

下面来做个实验。标准库模块random包含一个名为choice的函数,它从序列中随机选择一个元素。下面使用这个函数给变量提供一个值。

>>>from random import choice>>>x=choice(['Hello, world!’,[1,2.'e’,'e’,4]])

执行这些代码后,x可能包含字符串’Hello, world!',也可能包含列表[1,2,'e,'e,4]。具体是哪一个,你不知道也不关心。你只关心x包含多少个’e,而不管x是字符串还是列表你都能找到答案。为找到答案,可像前面那样调用count。

>>>x.count( e)

从上述结果看,x包含的应该是列表。但关键在于你无需执行相关的检查,只要x有一个名为count的方法,它将单个字符作为参数并返回一个整数就行。如果有人创建了包含这个方法的对象,你也可以像使用字符串和列表一样使用这种对象。

多态形式多样

每当无需知道对象是什么样的就能对其执行操作时,都是多态在起作用。这不仅仅适用于方法,我们还通过内置运算符和函数大量使用了多态。请看下面的代码:

>>>1+23>>>'Fish' +'license'Fishlicense

上述代码表明,加法运算符(+)既可用于数(这里是整数),也可用于字符串(以及其他类型的序列)。为证明这一点,假设你要创建一个将两个对象相加的add函数,可像下面这样定义它(这与模块operator中的函数add等价,但效率更低):

def add(x, y):return x+y

可使用众多不同类型的参数来调用这个函数。

>>> add(12)>>> add( Fish','license ')Fishlicense

这也许有点傻,但重点在于参数可以是任何支持加法的对象。如果要编写一个函数,通过打印一条消息来指出对象的长度,可以像下面这样做(它对参数的唯一要求是有长度,可对其执行函数len)。

def length message(x):print("The length of",repr(x),"is", len(x))

如你所见,

这个函数还使用了repr。repr是多态的集大成者之一,可用于任何对象,下面就来看看

>>>length message( FnordThe length ofFnord is 5>>>length message([1,2,3])The length of [1.2,3] is 3

很多函数和运算符都是多态的,你编写的大多数函数也可能如此,即便你不是有意为之。每当你使用多态的函数和运算符时,多态都将发挥作用。事实上,要破坏多态,唯一的办法是使用诸如type、issubclass、isinstance等函数显式地执行类型检查,但你应尽可能避免以这种方式破坏多态。重要的是,对象按你希望的那样行事,而非它是否是正确的类型(类)。然而,不要使用类型检查的禁令已不像以前那么严格。引入抽象基类和模块abc后,函数issubclass本身也是多态的了!

注意 这里讨论的多态形式是Python编程方式的核心,有时称为鸭子类型。这个术语源自如下说法:
“如果走起来像鸭子,叫起来像鸭子,那么它就是鸭子。

封装

封装(encapsulation)指的是向外部隐藏不必要的细节。这听起来有点像多态(无需知道对象的内部细节就可使用它)。这两个概念很像,因为它们都是抽象的原则。它们都像函数一样,可帮助你处理程序的组成部分,让你无需关心不必要的细节。

但封装不同于多态。多态让你无需知道对象所属的类(对象的类型)就能调用其方法,而封装让你无需知道对象的构造就能使用它。听起来还是有点像?下面来看一个使用了多态但没有使用封装的示例。假设你有一个名为OpenObject的类。

>>>o= openObject()# 对象就是这样创建的>>> o.set name( 'Sir Lancelot')>>> o.get name()Sir Lancelot

你(通过像调用函数一样调用类)创建一个对象,并将其关联到变量o,然后就可以使用方法set_name和get_name了(假设OpenObject支持这些方法)。一切都看起来完美无缺。然而,如果o将其名称存储在全局变量global_name中呢?

>>>global_nameSir Lancelot

这意味着使用OpenObject类的实例(对象)时,你需要考虑global_name的内容。事实上,必须确保无人能修改它。

>>>global_name ='Sir Gumby'>>> o.get_name()'Sir Gumby'

如果尝试创建多个OpenObject对象,将出现问题,因为它们共用同一个变量。

>>>o1= openObject()>>>o2 = openObject()>>>o1.set name('Robin Hood’)>>> o2.get name()Robin Hood

如你所见,设置一个对象的名称时,将自动设置另一个对象的名称。这可不是你想要的结果。

基本上,你希望对象是抽象的:当调用方法时,无需操心其他的事情,如避免干扰全局变量。如何将名称“封装”在对象中呢?没问题,将其作为一个属性即可。属性是归属于对象的变量,就像方法一样。(对象自己的番薯)实际上,方法差不多就是与函数相关联的属性。如果你使用属性而非全局变量重新编写前面的类,并将其重命名为ClosedObject,就可像下面这样使用它:

>>>c=Closedobject()>>>c.set name('Sir Lancelot’)>>> c.get name()Sir Lancelot

到目前为止一切顺利,但这并不能证明名称不是存储在全局变量中的。下面再来创建一个对象。

>>>r= ClosedObject()>>>r.set name('Sir Robin')>>>r.get name()‘Sir Robin'

从中可知正确地设置了新对象的名称(这可能在你的意料之中),但第一个对象现在怎么样了呢?

>>> c.get name()Sir Lancelot

其名称还在!因为这个对象有自己的状态。对象的状态由其属性(如名称)描述。对象的方法可能修改这些属性,因此对象将一系列函数(方法)组合起来,并赋予它们访问一些变量(属性)的权限,而属性可用于在两次函数调用之间存储值。

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

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

相关文章

用android studio模拟器,模拟安卓手机访问网页,使用Chrome 开发者工具查看控制台信息

web 网页项目在安卓手机打开时出现问题,想要查看控制台调试信息。记录一下使用android studio 模拟器访问的方式。 步骤如下: 1.安装android studio,新增虚拟设备(VDM- virtual device manager) 点击Virtual Device Manager后会…

【音视频】ffmpeg命令提取像素格式

1、提取YUV数据 提取yuv数据,并保持分辨率与原视频一致 使用-pix_fmt或-pixel_format指定yuv格式提取数据,并保持原来的分辨率 ffmpeg -i music.mp4 -t "01:00" -pixel_format yuv420p music.yuv提取成功后,可以使用ffplay指定y…

同为科技智能PDU在数据中心场景的应用与解决方案

数据中心当前处于一个快速发展和技术变革的特殊时期,全新的人工智能应用正在重塑整个世界,为社会带来便捷的同时,也为数据中心的发展带来了新的机遇和挑战。智能算例的爆发式增长,对数据中心提出了大算力、高性能的新需求&#xf…

deepseek在pycharm中的配置和简单应用

对于最常用的调试python脚本开发环境pycharm,如何接入deepseek是我们窥探ai代码编写的第一步,熟悉起来总没坏处。 1、官网安装pycharm社区版(免费),如果需要安装专业版,需要另外找破解码。 2、安装Ollama…

汽车一键启动按钮更换注意事项

汽车一键启动开关更换教程 一键启动开关是现代汽车中常见的便捷配置,但随着时间的推移,这个部件可能会出现失灵的情况。当一键启动开关发生故障时,许多车主选择自行更换。以下是整理的一键启动开关更换教程: 更换前的准备 选择匹…

群晖DS223 Docker搭建为知笔记

群晖DS223 Docker搭建为知笔记,打造你的专属知识宝库 一、引言 在数字化信息爆炸的时代,笔记软件成为了我们管理知识、记录灵感的得力助手。为知笔记,作为一款专注于工作笔记和团队协作的云笔记产品,以其丰富的功能和便捷的使用体…

①Modbus TCP转Modbus RTU/ASCII网关同步采集无需编程高速轻松组网

Modbus TCP转Modbus RTU/ASCII网关同步采集无需编程高速轻松组网https://item.taobao.com/item.htm?ftt&id784749793551 MODBUS TCP 通信单元 MODBUS TCP 转 RS485 MS-A1-50X1 系列概述 MS-A1-50X1 系列概述 MS-A1-50X1系列作为MODBUS TCP通信的服务器进行动作。可通…

BI 工具响应慢?可能是 OLAP 层拖了后腿

在数据驱动决策的时代,BI 已成为企业洞察业务、辅助决策的必备工具。然而,随着数据量激增和分析需求复杂化,BI 系统“卡”、“响应慢”的问题日益突出,严重影响分析效率和用户体验。 本文将深入 BI 性能问题的根源,并…

Elasticsearch 2025/3/7

高性能分布式搜索引擎。 数据库模糊搜索比较慢,但用搜索引擎快多了。 下面是一些搜索引擎排名 Lucene是一个Java语言的搜索引擎类库(一个工具包),apache公司的顶级项目。 优势:易扩展、高性能(基于倒排索引…

探索AI对冲基金:开源自动化交易系统的革新之路

在量化交易领域,人工智能技术的应用正悄然改变传统对冲基金的运作模式。GitHub上的开源项目ai-hedge-fund为开发者和金融从业者提供了一个独特的实践平台。该项目通过多智能体系统架构,整合市场数据分析、量化策略生成、风险管理和投资组合优化等核心功能,实现了从数据采集到…

prompt大师高效提示词解析

Prompt大师李继刚高效提示词示例解析 一、「汉语新解」提示词 核心结构 采用Lisp语言框架嵌套中文语义,通过(defun 新汉语老师 ()...)定义角色风格(融合奥斯卡王尔德、鲁迅的批判性语言),用(隐喻 (一针见血...))构建解释逻辑链。…

【GPT入门】第8课 大语言模型的自洽性

【GPT入门】第8课 大语言模型的自洽性 1.自洽性概念2.代码(观察执行结果)3.自洽性核心思想 1.自洽性概念 大模型的自洽性(self - consistency)是指在推理阶段,大模型通过生成多个答案并选择出现频率最高的那个&#x…

[动手学习深度学习]12.权重衰退

1.介绍 权重衰退是常见的处理过拟合的方法 控制模型容量方法 把模型控制的比较小,即里面参数比较少使参数选择范围小 约束就是正则项 每个特征的权重都大会导致模型复杂,从而导致过拟合。 控制权重矩阵范数可以使得减少一些特征的权重,甚至…

RabbitMq--消息可靠性

12.消息可靠性 1.消息丢失的情况 生产者向消息代理传递消息的过程中,消息丢失了消息代理( RabbitMQ )把消息弄丢了消费者把消息弄丢了 那怎么保证消息的可靠性呢,我们可以从消息丢失的情况入手——从生产者、消息代理&#xff0…

2019年蓝桥杯第十届CC++大学B组真题及代码

目录 1A:组队(填空5分_手算) 2B:年号字符(填空5分_进制) 3C:数列求值(填空10分_枚举) 4D:数的分解(填空10分) 5E:迷宫…

UI-APP---基于HBuilder X的微信小程序

目录 概要 Uni-app 和 HBuilderX 的关系 技术名词解释 ui-app: 概念: 核心特点: 技术细节 基本步骤: 开发流程 项目功能分析: ①首页包括公共头部、导航栏、轮播图、视频列表区域。 ②视频详情页包括公共头部区域、视频详情区域、…

多宠识别:基于计算机视觉的智能宠物管理系统架构解析

一、行业痛点与技术方案演进 在多宠家庭场景中,传统方案面临三大技术瓶颈: 1. 生物特征混淆:同品种/毛色宠物识别准确率低于65% 2. 动态场景适应:进食/奔跑状态下的误检率达30% 3. 数据孤岛问题:离线设备无法实现持续…

论文阅读分享——UMDF(AAAI-24)

概述 题目:A Unified Self-Distillation Framework for Multimodal Sentiment Analysis with Uncertain Missing Modalities 发表:The Thirty-Eighth AAAI Conference on Artificial Intelligence (AAAI-24) 年份:2024 Github:暂…

Unity组件大全之 Layout 组件 |(27)Content Size Fitter 内容大小适配器

📂 Unity 开发资源汇总 | 插件 | 模型 | 源码 💓 欢迎访问 Unity 打怪升级大本营 在 Unity 的 UI 系统中,Content Size Fitter 是一个重要的布局组件,能够根据内容动态调整 UI 元素的尺寸。它通过自动检测内容的大小来改变元素的宽…

<3D建模>.max文件转换为.fbx文件

今天在使用unity3D开发软件时,下载了.max文件。大家知道.max文件是3DMax生成的文件,然而我的电脑中也没有3DMax,而unity中的场景文件通常要用到.fbx文件,这可怎么办呢?难道要去下载一个3DMax软件吗?其实并不…