Python知识点13---面向对象的编程
提前说一点:如果你是专注于Python开发,那么本系列知识点只是带你入个门再详细的开发点就要去看其他资料了,而如果你和作者一样只是操作其他技术的Python API那就足够了。
Python是一个完全面向对象开发的语言,它的一切都以对象的方式操作
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
局部变量:定义在方法中的变量,只作用于当前实例的类。
实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
定义一个类的语法如下,注意如果你用的是Python2,那么不要写objeck,不然会报错的
class ClassName(objeck):'类的帮助信息' #类文档字符串class_suite #类体#类的实例方法def aaa(self) :return
实例化类,生成对象语法如下
变量名 = 类名() ---不需要其他语言那样的new
Python的类里面,和其他语言不同的就是,有时方法中会多一个 self,这个变量你要使用的时候,一般都是放在第一个参数位,并且代表对象本身,下面这个例子可以解释这一点
class Test:def prt(self):print(self)t = Test()
print(t)
t.prt()结果发现指向的都是同一个对象:
<__main__.Test instance at 0x10d066878>
<__main__.Test instance at 0x10d066878>
切记:对于 self 本身来说,它不是一个定死的关键字,我们换成其他的名字也可以,只是在开发中我们按照惯例,把它写在了第一个参数位,并且起名为 self ,它本身其实是和JAVA的this对象等价的,只不过Python需要在参数位声明一下而已
而且当你使用了self的时候,在传递参数时,不需要在意它的值,因为可以自动补齐,如下
class Test :def fun_name(self,b,c):print(b+str(c))a = Test()
a.fun_name('忽略self正常传参',21)
结果:忽略self正常传参21
对于Python的类来说,也是拥有属性的,我们在类的内部,类实体方法的外部,书写属性即可,但是切记在类中书写属性的时候一定要给一个初值,不然访问的时候会报错
class Test :age = ''def fun_test():print('llll')
在使用这个类创建对象之后,对象会拥有类的所有东西,属性自然也包括其中,调用时语法如下,这一点在Python中叫做 “类外面获取对象属性”
对象名.属性名 #调用获取
对象名.属性名 = 值 #修改
但是注意,Python允许一个对象拥有属于自己的属性,这种属性不需要在类中定义,直接使用对象调用就可以,会自动生成一个数据这个对象自己的属性,其他对象没有,下面这个例子可以解释这一点,这一点在Python中也叫做 “类外面添加对象属性”
class Test :def fun_name():print('llll')a = Test()
b = Test()a.age = '12'
print(a.age)
print(b.age)结果会报错,提示对象b没有age属性:
12
Traceback (most recent call last):File "main.py", line 12, in <module>print(b.age)
AttributeError: Test instance has no attribute 'age'
这个时候有的小伙伴可能就会疑惑,有类外面获取对象属性、类外面添加对象属性,这两点都聚焦在对象的身上,和类的关系不是很明显,其实Python还有最后一种相关操作,叫做“在类内部获取对象属性”,对于这一点,个人认为其实是Python提供给我们开发者的一种辅助,防止我们由于其他因素导致访问不到对象的属性,比如被局部变量或者其他变量干扰,操作方式如下
class Test :age = 12def fun_name(self):print(self.age)a = Test()
a.fun_name()
其实就是self的应用,不过注意,这种操作可以和类外部添加属性那样直接调用一个原先没有的属性
class Test :def fun_name(self):print(self.age)a = Test()
a.age = 10
a.fun_name()
现在我猜测大家或许会混乱,没关系,记住核心的一点:在Python中,可以像常规那样使用对象和类,只是Python除此之外,允许一个属性在使用的时候,是从无到有的,也就是没有被预先定义的
其实对于self来说,它不止可以调用我们自己定义的属性,它还带有着其他的东西,有兴趣大家可以在其他地方找一找资料,比如可以获取对象实例化的类名
class Test :def fun_name(self):print(self.__class__)a = Test()
a.fun_name()结果:__main__.Test
对于对象的属性,Python其实有着其他的方式可以调用
getattr(obj, name[, default]) : 访问对象的属性。
hasattr(obj,name) : 检查是否存在一个属性。
setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
delattr(obj, name) : 删除属性。hasattr(emp1, 'age') # 如果存在 'age' 属性返回 True。
getattr(emp1, 'age') # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(emp1, 'age') # 删除属性 'age'
Python类的本身其实也有自带的被规定的属性,俗称类属性,为什么说它被规定呢?这个后面我会解释
调用的时候用 类名.类属性 就可以了__dict__ : 类的属性(包含一个字典,由类的数据属性组成)
__doc__ :类的文档字符串
__name__: 类名
__module__: 类定义所在的模块
__bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
有意思的是我们通过类名可以直接将自己定义的属性获取到,这个时候,这个属性也叫做类属性
下面我们了解一下,在Python中对象是如何被垃圾回收的
在Python中只有一种垃圾回收机制,就是引用计数法,在 Python 内部记录着所有使用中的对象各有多少引用。
一个内部跟踪变量,称为一个引用计数器。
当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。但是回收不是"立即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。
垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使用引用计数是不够的。Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(即未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来, 试图清理所有未引用的循环,其实说白了就是有a、b两个对象,它们独立与其他对象,产生较为单独的一对相互引用关系,这种对象时间长了,也会被回收掉
特别注意一个对象被回收时,会调用它的__del__方法,这个方法是用来回收对象的,但大家不要纠结,后面我会单独说这种有四个下滑线的方法,是干什么的
下面我们来了解一下类的继承,类继承语法如下
class 派生类名(基类名):...
Python的类继承的时候,和其他语言一样有着注意点:
1、如果在子类中需要父类的构造方法就需要显式的调用父类的构造方法,或者不重写父类的构造方法。实例如下
当你没有重写构造方法时:
class Father():def __init__(self, name):self.name=namedef getName(self):return 'Father ' + self.nameclass Son(Father):def getName(self):return 'Son '+self.nameson=Son('runoob')
print ( son.getName() )结果:Son runoob
从结果中你可以发现,传入的name值作用在了父类的构造器上-----------------------------------------------------------------------------
当你重写了子类的构造方法,但是没有调用父类的时候:
class Father():def __init__(self, name):self.name=namedef getName(self):return 'Father ' + self.nameclass Son(Father):def __init__(self, name):print ( "hi" )self.name = namedef getName(self):return 'Son '+self.nameson=Son('runoob')
print ( son.getName() )结果:
hi
Son runoob
从结果来看,发现并没有调用父类的构造方法------------------------------------------------------------
当你重写了子类的构造方法,并调用了父类的构造方法时:
class Father():def __init__(self, name):self.name = nameprint("这里是父类")class Son(Father):def __init__(self, name):#第一种调用方法:super(Son, self).__init__(name)#第二种调用方法:Father.__init__(self,name)print ("hi")self.name = namedef getName(self):return 'Son '+self.nameson=Son('runoob')
print ( son.getName() )
结果:
这里是父类
hi
Son runoob
2、在调用基类的方法时,基类的方法必须有self参数,不然无法执行,对于这一点其实大家养成写方法参数要带上self的习惯就可以了
基类没有self:
class Father():def __init__(self, name):self.name = namedef nnn():print('父类方法')class Son(Father):def __init__(self, name):Father.__init__(self,name)self.name = nameson=Son('runoob')
son.nnn()
结果报错:
Traceback (most recent call last):File "main.py", line 17, in <module>son.nnn()
TypeError: nnn() takes no arguments (1 given)----------------------------------------------------------------
基类有self
class Father():def __init__(self, name):self.name = namedef nnn(self):print('父类方法')class Son(Father):def __init__(self, name):Father.__init__(self,name)self.name = nameson=Son('runoob')
son.nnn()
结果:父类方法
3、Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
值得高兴的是Python支撑多继承
class A: # 定义类 A
.....class B: # 定义类 B
.....class C(A, B): # 继承类 A 和 B
.....
还提供了两个检查函数
issubclass() 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(子类,父类)
isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true
Python也支持多态,在重写父类方法的时候也要注意self
class Father():def __init__(self, name):self.name = namedef nnn(self):print('父类方法')class Son(Father) :def __init__(self, name) :Father.__init__(self,name)self.name = namedef nnn(self,age) :print('子类方法' + str(age))def nnn(self,age,ppp) :print('子类方法' + str(age) + str(ppp))a = Son('Tom')
a.nnn(10)
a.nnn(10,20)
结果:
子类方法10
子类方法1020
如果看了我写的公共方法篇,一定知道加法是合并的意思,而有趣的是Python的对象也支持这样的操作,不过想要对象之间执行合并你需要重写__add__方法
class Vector:def __init__(self, a, b):self.a = aself.b = bdef __str__(self):return 'Vector (%d, %d)' % (self.a, self.b)def __add__(self,other):return Vector(self.a + other.a, self.b + other.b)v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2
结果:Vector (7, 8)
值得一提的是,在Python中类也是有静态方法的
class Father():def __init__(self, name):self.name = name@staticmethoddef nnn(self):print('静态方法')Father.nnn()
a = Father('Tom')
a.nnn()
相关文章:
Python知识点13---面向对象的编程
提前说一点:如果你是专注于Python开发,那么本系列知识点只是带你入个门再详细的开发点就要去看其他资料了,而如果你和作者一样只是操作其他技术的Python API那就足够了。 Python是一个完全面向对象开发的语言,它的一切都以对象的…...
Android Dialog软键盘弹出问题完美解决办法
一、问题: Dialog中有输入框时,显示后无法自动弹起软键盘,原因就不赘述了,自行Google。 一、解决办法: 开启独立线程,线程中使用while循环,循环调用弹起软键盘方法,直至showSoftI…...

【C++】C++入门1.0
鼠鼠最近在学C,那么好,俺来做笔记了! 目录 1.C关键字(C98) 2.命名空间 2.1.命名空间定义 2.2.命名空间的使用 3.C的输入&&输出 4.缺省参数 4.1缺省参数概念 4.2.缺省参数的分类 5.函数重载 5.1.函数重载概念 5.2.C支持函数…...

springboot实现文件上传功能,整合云服务
文章目录 这是springboot案例的,文件上传功能的拆分,本篇将带大家彻底了解文件上传功能,先从本地存储再到云存储,全网最详细版本,保证可以学会,可以了解文件上传功能的开发文件上传功能剖析进行书写一个小的文件上传文件上传的文件三要素首先表单提交的方式要是 post方式,第二个…...

接口interfance的基本使用
一.为什么有接口? 接口:就是一种规则。 二.接口的定义和使用 1.接口用关键字interface来定义 public interface 接口名{} 2.接口不能实例化 3.接口和类之间是实现关系,通过implements关键字表示 4.接口的子类(实现类) 注意1: 接口和类的实现关系…...
Gitlub如何删除分支(删除远程分支+本地分支)
目录 背景 删除方法 总结 背景 想要删除自己在本地创建的并已上传到远程分支中的分支。 删除方法 1)删除远程分支 git push origin --delete brannchname 2)删除本地分支 先切换到其他分支 git checkout otherbranch 删除本地分支 git bran…...

使用RSA算法加密字符串:从基础到实现 - Python
在现代数据安全中,加密算法起着至关重要的作用。特别是非对称加密算法,如RSA(Rivest-Shamir-Adleman),广泛应用于保护敏感信息的传输。本文将详细介绍如何使用RSA算法加密和解密字符串,包括生成密钥对、加密…...
MFC实现守护进程,包括开机自启动、进程单例、进程查询、进程等待、重启进程、关闭进程
在Windows平台上实现一个守护进程,由于与系统有关,所有使用MFC来实现是最合适的,被守护的进程则不限语言。废话不多,直接开整。 目录 1. 开机自启动 2. 进程单例 3. 进程查询 4. 进程等待 5. 重启进程 6. 关闭进程 7、最后…...
Spark SQL数据源 - Parquet文件
当使用Spark SQL处理Parquet文件时,你可以使用spark.read.parquet()方法从文件系统中加载Parquet数据到一个DataFrame中。Parquet是一种列式存储格式,非常适合用于大数据集,因为它提供了高效的压缩和编码方案。 以下是一个简单的例子&#x…...

eNsp——两台电脑通过一根网线直连通信
一、拓扑结构 二、电脑配置 ip和子网掩码,配置两台电脑处于同一网段 三、测试 四、应用 传文件等操作,可以在一台电脑上配置FTP服务器...

杂牌记录仪TS视频流恢复方法
大多数的记录仪都采用了MP4/MOV文件方案,极少数的可能在用AVI文件,极极少数的在用TS文件方案。很多人可能不太解TS文件,这是一种古老的视频文件结构,下边这个案例我们来看下TS视频文件的恢复方法。 故障存储:8G存储卡/fat32文件系…...

十_信号7-信号集
int sigemptyset(sigset_t *set); 清空信号集 int sigfillset(sigset_t *set); 填充满 信号集 int sigaddset(sigset_t *set, int signum); 向信号集中添加信号 int sigdelset(sigset_t *set, int signum); 从型号集中删除信号 int sigismember(const sigset_t *set, int s…...
GPT-4o
微软最新发布的CopilotPC采用了OpenAI最新的GPT-4o技术,新增了多项强大功能。以下是主要的新增功能: 更强大的AI处理能力:CopilotPC采用了专门用于AI处理的特殊芯片,使得电脑能够处理更多的人工智能任务,而无需调用云…...

32位与64位程序下函数调用的异同——计科学习中缺失的内容
前言 今天,通过一个有趣的案例,从反编译的角度看一下C语言中函数参数是如何传递的。 创建main.c文件,将下面实验代码拷贝到main.c文件中。 # main.c #include <stdio.h>int test(int a, int b, int c, int d, int e, int f, int g, …...

Python爬虫实战(实战篇)—16获取【百度热搜】数据—写入Ecel(附完整代码)
文章目录 专栏导读背景结果预览1、爬取页面分析2、通过返回数据发现适合利用lxmlxpath3、继续分析【小说榜、电影榜、电视剧榜、汽车榜、游戏榜】4、完整代码总结 专栏导读 🔥🔥本文已收录于《Python基础篇爬虫》 🉑🉑本专栏专门…...

js切割数组的两种方法slice(),splice()
slice() 返回一个索引和另一个索引之间的数据(不改变原数组),slice(start,end)有两个参数(start必需,end选填),都是索引,返回值不包括end 用法和截取字符串一样 splice() 用来添加或者删除数组的数据,只返回被删除的数据,类型为数组(改变原数组) var heroes["李白&q…...

【计算机毕设】基于SpringBoot的医院管理系统设计与实现 - 源码免费(私信领取)
免费领取源码 | 项目完整可运行 | v:chengn7890 诚招源码校园代理! 1. 研究目的 本项目旨在设计并实现一个基于SpringBoot的医院管理系统,以提高医院管理效率,优化医疗服务流程,提升患者就诊体验…...

导线防碰撞警示灯:高压线路安全保障
导线防碰撞警示灯:高压线路安全保障 在广袤的大地上,高压线路如同血脉般纵横交错,然而,在这看似平静的电力输送背后,却隐藏着不容忽视的安全隐患。特别是在那些输电线路跨越道路、施工等区域的路段,线下超…...
【LeetCode 77. 组合】
1. 题目 2. 分析 本题有个难点在于如何保存深搜得到的结果?总结了一下,深搜处理的代码,关于返回值有三大类。 第一类:层层传递,将最深层的结果传上来;这类题有:【反转链表】 第二类࿱…...
element-ui组件table去除下方滚动条,实现鼠标左右拖拽移动表格
时隔多日,再次遇到值得记录的问题。 需求 项目前端使用vue框架,页面使用element-ui进行页面快速搭建。默认的table组件当表格过长时,下方会出现横向的滚动条,便于用户对表格进行左右滑动。考虑到页面美观问题,滚动条…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...