python面向对象 | OOP相关概念

news/2024/5/19 5:44:18 标签: python, 人工智能, OOP, 软件工程, 反射

在这里插入图片描述

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C++、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。关注公粽号 《机器和智能》 回复关键词 “python项目实战” 即可获取美哆商城视频资源!


博主介绍:
CSDN博客专家,CSDN优质创作者,CSDN实力新星,CSDN内容合伙人;
阿里云社区专家博主;
华为云社区云享专家;
51CTO社区入驻博主,掘金社区入驻博主,支付宝社区入驻博主,博客园博主。


python面向对象 —— OOP相关概念


专栏:《python从入门到实战》


pythonOOP_18">python中关于OOP的一些概念

抽象/实现
抽象指对现实世界问题和实体的本质表现,行为和特征建模,建立一个相关的子集,可以用于 绘程序结构,从而实现这种模型。抽象不仅包括这种模型的数据属性,还定义了这些数据的接口。
对某种抽象的实现就是对此数据及与之相关接口的现实化(realization)。现实化这个过程对于客户 程序应当是透明而且无关的。
封装/接口
封装描述了对数据/信息进行隐藏的观念,它对数据属性提供接口和访问函数。通过任何客户端直接对数据的访问,无视接口,与封装性都是背道而驰的,除非程序员允许这些操作。作为实现的 一部分,客户端根本就不需要知道在封装之后,数据属性是如何组织的。在Python中,所有的类属性都是公开的,但名字可能被“混淆”了,以阻止未经授权的访问,但仅此而已,再没有其他预防措施了。这就需要在设计时,对数据提供相应的接口,以免客户程序通过不规范的操作来存取封装的数据属性。
注意:封装绝不是等于“把不想让别人看到、以后可能修改的东西用private隐藏起来”
真正的封装是,经过深入的思考,做出良好的抽象,给出“完整且最小”的接口,并使得内部细节可以对外透明
(注意:对外透明的意思是,外部调用者可以顺利的得到自己想要的任何功能,完全意识不到内部细节的存在)
合成
合成扩充了对类的 述,使得多个不同的类合成为一个大的类,来解决现实问题。合成 述了 一个异常复杂的系统,比如一个类由其它类组成,更小的组件也可能是其它的类,数据属性及行为, 所有这些合在一起,彼此是“有一个”的关系。
派生/继承/继承结构
派生描述了子类衍生出新的特性,新类保留已存类类型中所有需要的数据和行为,但允许修改或者其它的自定义操作,都不会修改原类的定义。
继承描述了子类属性从祖先类继承这样一种方式
继承结构表示多“代”派生,可以述成一个“族谱”,连续的子类,与祖先类都有关系。
泛化/特化
基于继承
泛化表示所有子类与其父类及祖先类有一样的特点。
特化描述所有子类的自定义,也就是,什么属性让它与其祖先类不同。
多态与多态性
多态指的是同一种事物的多种状态:水这种事物有多种不同的状态:冰,水蒸气
多态性的概念指出了对象如何通过他们共同的属性和动作来操作及访问,而不需考虑他们具体的类。
冰,水蒸气,都继承于水,它们都有一个同名的方法就是变成云,但是冰.变云(),与水蒸气.变云()是截然不同的过程,虽然调用的方法都一样
自省/反射
自省也称作反射,这个性质展示了某对象是如何在运行期取得自身信息的。如果传一个对象给你,你可以查出它有什么能力,这是一项强大的特性。如果Python不支持某种形式的自省功能,dir和type内建函数,将很难正常工作。还有那些特殊属性,像__dict__,__name__及__doc__。

软件工程思想

软件的开发其实一整套规范,我们所学的只是其中的一小部分,一个完整的开发过程,需要明确每个阶段的任务,在保证一个阶段正确的前提下再进行下一个阶段的工作,称之为软件工程
面向对象的软件工程包括下面几个部分:

1.面向对象分析(object oriented analysis ,OOA)
软件工程中的系统分析阶段,要求分析员和用户结合在一起,对用户的需求做出精确的分析和明确的表述,从大的方面解析软件系统应该做什么,而不是怎么去做。面向对象的分析要按照面向对象的概念和方法,在对任务的分析中,从客观存在的事物和事物之间的关系,贵南出有关的对象(对象的‘特征’和‘技能’)以及对象之间的联系,并将具有相同属性和行为的对象用一个类class来标识。
建立一个能反映这是工作情况的需求模型,此时的模型是粗略的。
2. 面向对象设计(object oriented design,OOD)
根据面向对象分析阶段形成的需求模型,对每一部分分别进行具体的设计。
首先是类的设计,类的设计可能包含多个层次(利用继承与派生机制)。然后以这些类为基础提出程序设计的思路和方法,包括对算法的设计。
在设计阶段并不牵涉任何一门具体的计算机语言,而是用一种更通用的描述工具(如伪代码或流程图)来描述
3. 面向对象编程(object oriented programming,OOP
根据面向对象设计的结果,选择一种计算机语言把它写成程序,可以是python
4. 面向对象测试(object oriented test,OOT)
在写好程序后交给用户使用前,必须对程序进行严格的测试,测试的目的是发现程序中的错误并修正它。
面向对的测试是用面向对象的方法进行测试,以类作为测试的基本单元。
5. 面向对象维护(object oriendted soft maintenance,OOSM)
正如对任何产品都需要进行售后服务和维护一样,软件在使用时也会出现一些问题,或者软件商想改进软件的性能,这就需要修改程序。
由于使用了面向对象的方法开发程序,使用程序的维护比较容易。
因为对象的封装性,修改一个对象对其他的对象影响很小,利用面向对象的方法维护程序,大大提高了软件维护的效率,可扩展性高。

在面向对象方法中,最早发展的肯定是面向对象编程(OOP),那时OOA和OOD都还没有发展起来,因此程序设计者为了写出面向对象的程序,还必须深入到分析和设计领域,尤其是设计领域,那时的OOP实际上包含了现在的OOD和OOP两个阶段,这对程序设计者要求比较高,许多人感到很难掌握。
现在设计一个大的软件,是严格按照面向对象软件工程的5个阶段进行的,这个5个阶段的工作不是由一个人从头到尾完成的,而是由不同的人分别完成,这样OOP阶段的任务就比较简单了。程序编写者只需要根据OOD提出的思路,用面向对象语言编写出程序既可。

反射的概念和用途

检查对象是否有类实例化,是否是派生类的方法:

  • isinstance(obj,cls)检查是否obj是否是类 cls 的对象
  • issubclass(sub, super)检查sub类是否是 super 类的派生类

反射主要是指程序可以访问、坚持和修改它本身状态或行为的一种能力(自省)。python面向对象中的反射是指,通过字符串的形式操作对象相关属性,在python中一切皆对象。

实现自省的函数 – 适用于一切对象和类

python">#-------------------------------------------------------------------------
hasattr(object,name) #判断object中有没有一个name字符串对应的方法或属性
#--------------------------------------------------------------------------
def getattr(object, name, default=None): # known special case of getattr
    """
    getattr(object, name[, default]) -> value

    Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    When a default argument is given, it is returned when the attribute doesn't
    exist; without it, an exception is raised in that case.
    """
    pass
#--------------------------------------------------------------------------
def setattr(x, y, v): # real signature unknown; restored from __doc__
    """
    Sets the named attribute on the given object to the specified value.

    setattr(x, 'y', v) is equivalent to ``x.y = v''
    """
    pass
#--------------------------------------------------------------------------
def delattr(x, y): # real signature unknown; restored from __doc__
    """
    Deletes the named attribute from the given object.

    delattr(x, 'y') is equivalent to ``del x.y''
    """
    pass

通过反射可以实现两大好处:
①实现可插拔机制
可以事先定义好接口,接口只有在被完成后才会真正执行,即实现了即插即用,这其实就是后期绑定的意思,我们可以事先写好接口,后期再去实现接口功能。

python">#A还没实现全部功能
class FtpClient:
    'ftp客户端,但是还么有实现具体的功能'
    def __init__(self,addr):
        print('正在连接服务器[%s]' %addr)
        self.addr=addr
#不影响B的代码编写
#from module import FtpClient
f1=FtpClient('192.168.1.1')
if hasattr(f1,'get'):
    func_get=getattr(f1,'get')
    func_get()
else:
    print('---->不存在此方法')
    print('处理其他的逻辑')

②动态导入模块(基于反射当前模块)

  • 字符串的方式导入:import(‘mode’)
  • 模块名的方式导入:import modename

有时候我们可能通过一系列操作获得了一个文件的名称,在程序中是字符串的形式获得的,那么我们在程序中就要以字符串的形式导入。
m = __import__(‘mode.mode1’) 不管套多少层,最后返回的都是最顶层的模块mode,也就是说m = mode。我们要调用mode1模块的方法应该这样来操作m.mode1.func(),而不是m.func()。
如果我们用import importlib模块下的m = import.import_module(‘mode.mode1’)这样来以字符串的形式导入模块,那么m返回的就是mode.mode1,可以直接用m调用mode1的函数,m.func()。
导入模块的时候,如果被导入的模块中有私有的函数(_开头),如果我们使用from mode import *的方式导入,那么将无法使用被导入模块的私有函数;如果显示导入的话from mode import _func,那么这个私有函数时可以使用的。由此也可看出,python中的私有只是一种约定,而不是强制。
python中一切皆对象,import导入包的时候,会自动执行包下面的__init__文件,这是为什么呢?实际上import导入包的过程就相当于实例化的过程,实例化的时候会触发__init__方法。
一切皆对象,类本质上也是对象(类是由一个类产生的),所以关于反射对对象的操作,也可以对类进行操作。
反射中,都是基于字符串来自省的,而动态导入模块也是通过字符串的形式导入模块的,实际上动态导入模块底层就是基于反射来做的。


在这里插入图片描述
在这里插入图片描述



http://www.niftyadmin.cn/n/5350729.html

相关文章

前端大厂面试题探索编辑部——第二期

目录 题目 单选题1 题解 关于TCP 关于UDP 单选题2 题解 A选项的HTTP是否是无状态协议 B选项的HTTP支持的方法 C选项的关于HTTP的状态码 D选项HTTP协议的传输格式 题目 单选题1 1.以下哪个描述是关于 TCP 和 UDP 的区别() A. TCP 是无连接的…

Linux 远程服务器与本地互传文件

本地传远程服务器: 你可以使用 scp 命令将整个文件夹复制到远程服务器上。以下是一个示例命令: scp -r /home/wanghaiyang/Documents/DockerServer/docker_compose_project/apollo apollo254.564.257.12:/home/apollo/code/docker_compose/ 请确保将 /home/wangh…

对于循环的一次探索

写算法题的时候突然想到&#xff0c;为什么循环内定义变量不会算作是重复定义&#xff0c;以及变量作用域问题&#xff0c;为此&#xff0c;进行了一次探索 c&#xff1a; 代码&#xff1a; #include <stdio.h> int main() {int a 0;int* b &a;for (int i 0; i …

用Flask打造一个大模型智能问答WEB网站

目前已经有很多类似GPT的大模型开源,可以提供类似ChatGPT的智能问答功能。我也基于这些开源模型,用Flask来建立一个智能问答网站,可以方便用户建立自己的ChatGPT系统。 这个网站需要提供用户登录功能,对已登录的用户,可以在网站上提出问题,并由大模型处理后返回答案。演…

Qt/QML编程之路:qml通过C++传递变量给另一个qml(42)

Qml的项目设计时,不可避免涉及到qml之间的调用,此时很正常想象到的是如何进行事件传输和参数传输。一般就是在qml文件中定义property int, 或者定义 signal mySignal。 我就遇到了这么一种情况,需要把一个image的source,也就是图片的路径信息,从设置界面直接传递到要设置背…

佳博GP3120条码打印机驱动安装指导

为了您更轻松的使用佳博GP3120条码打印机&#xff0c;请按照以下具体步骤完成安装打印机驱动。 步骤一&#xff1a;右击解压安装包&#xff1b; 步骤二&#xff1a;双击安装&#xff1b; 步骤三&#xff1a;选择第一个&#xff0c;然后下一步&#xff1b; 步骤四&#xff1a;默…

【git】git远程仓库迁移后 本地批量修改远程地址

当公司迁移远程git仓库时&#xff0c;我们需要修改git仓库的远程仓库的地址&#xff0c;可以一个一个的修改&#xff0c;但是如果项目比较多并且改的东西都一样的话&#xff0c;使用脚本修改就比较方便了。 预备知识&#xff1a; 查看远程仓库地址&#xff1a; git remote -…

市场复盘总结 20240122

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 昨日主题投资 连板进级率 6/39 15.3% 二进三&#xff1a; 进级率低 0% 最常用的二种方法&#xff1a; 方法…