当前位置: 首页 > news >正文

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---面向对象的编程

提前说一点&#xff1a;如果你是专注于Python开发&#xff0c;那么本系列知识点只是带你入个门再详细的开发点就要去看其他资料了&#xff0c;而如果你和作者一样只是操作其他技术的Python API那就足够了。 Python是一个完全面向对象开发的语言&#xff0c;它的一切都以对象的…...

Android Dialog软键盘弹出问题完美解决办法

一、问题&#xff1a; Dialog中有输入框时&#xff0c;显示后无法自动弹起软键盘&#xff0c;原因就不赘述了&#xff0c;自行Google。 一、解决办法&#xff1a; 开启独立线程&#xff0c;线程中使用while循环&#xff0c;循环调用弹起软键盘方法&#xff0c;直至showSoftI…...

【C++】C++入门1.0

鼠鼠最近在学C&#xff0c;那么好&#xff0c;俺来做笔记了&#xff01; 目录 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的基本使用

一.为什么有接口&#xff1f; 接口:就是一种规则。 二.接口的定义和使用 1.接口用关键字interface来定义 public interface 接口名{} 2.接口不能实例化 3.接口和类之间是实现关系,通过implements关键字表示 4.接口的子类(实现类) 注意1&#xff1a; 接口和类的实现关系…...

Gitlub如何删除分支(删除远程分支+本地分支)

目录 背景 删除方法 总结 背景 想要删除自己在本地创建的并已上传到远程分支中的分支。 删除方法 1&#xff09;删除远程分支 git push origin --delete brannchname 2&#xff09;删除本地分支 先切换到其他分支 git checkout otherbranch 删除本地分支 git bran…...

使用RSA算法加密字符串:从基础到实现 - Python

在现代数据安全中&#xff0c;加密算法起着至关重要的作用。特别是非对称加密算法&#xff0c;如RSA&#xff08;Rivest-Shamir-Adleman&#xff09;&#xff0c;广泛应用于保护敏感信息的传输。本文将详细介绍如何使用RSA算法加密和解密字符串&#xff0c;包括生成密钥对、加密…...

MFC实现守护进程,包括开机自启动、进程单例、进程查询、进程等待、重启进程、关闭进程

在Windows平台上实现一个守护进程&#xff0c;由于与系统有关&#xff0c;所有使用MFC来实现是最合适的&#xff0c;被守护的进程则不限语言。废话不多&#xff0c;直接开整。 目录 1. 开机自启动 2. 进程单例 3. 进程查询 4. 进程等待 5. 重启进程 6. 关闭进程 7、最后…...

Spark SQL数据源 - Parquet文件

当使用Spark SQL处理Parquet文件时&#xff0c;你可以使用spark.read.parquet()方法从文件系统中加载Parquet数据到一个DataFrame中。Parquet是一种列式存储格式&#xff0c;非常适合用于大数据集&#xff0c;因为它提供了高效的压缩和编码方案。 以下是一个简单的例子&#x…...

eNsp——两台电脑通过一根网线直连通信

一、拓扑结构 二、电脑配置 ip和子网掩码&#xff0c;配置两台电脑处于同一网段 三、测试 四、应用 传文件等操作&#xff0c;可以在一台电脑上配置FTP服务器...

杂牌记录仪TS视频流恢复方法

大多数的记录仪都采用了MP4/MOV文件方案&#xff0c;极少数的可能在用AVI文件&#xff0c;极极少数的在用TS文件方案。很多人可能不太解TS文件&#xff0c;这是一种古老的视频文件结构&#xff0c;下边这个案例我们来看下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技术&#xff0c;新增了多项强大功能。以下是主要的新增功能&#xff1a; 更强大的AI处理能力&#xff1a;CopilotPC采用了专门用于AI处理的特殊芯片&#xff0c;使得电脑能够处理更多的人工智能任务&#xff0c;而无需调用云…...

32位与64位程序下函数调用的异同——计科学习中缺失的内容

前言 今天&#xff0c;通过一个有趣的案例&#xff0c;从反编译的角度看一下C语言中函数参数是如何传递的。 创建main.c文件&#xff0c;将下面实验代码拷贝到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、完整代码总结 专栏导读 &#x1f525;&#x1f525;本文已收录于《Python基础篇爬虫》 &#x1f251;&#x1f251;本专栏专门…...

js切割数组的两种方法slice(),splice()

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

【计算机毕设】基于SpringBoot的医院管理系统设计与实现 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 本项目旨在设计并实现一个基于SpringBoot的医院管理系统&#xff0c;以提高医院管理效率&#xff0c;优化医疗服务流程&#xff0c;提升患者就诊体验…...

导线防碰撞警示灯:高压线路安全保障

导线防碰撞警示灯&#xff1a;高压线路安全保障 在广袤的大地上&#xff0c;高压线路如同血脉般纵横交错&#xff0c;然而&#xff0c;在这看似平静的电力输送背后&#xff0c;却隐藏着不容忽视的安全隐患。特别是在那些输电线路跨越道路、施工等区域的路段&#xff0c;线下超…...

【LeetCode 77. 组合】

1. 题目 2. 分析 本题有个难点在于如何保存深搜得到的结果&#xff1f;总结了一下&#xff0c;深搜处理的代码&#xff0c;关于返回值有三大类。 第一类&#xff1a;层层传递&#xff0c;将最深层的结果传上来&#xff1b;这类题有&#xff1a;【反转链表】 第二类&#xff1…...

element-ui组件table去除下方滚动条,实现鼠标左右拖拽移动表格

时隔多日&#xff0c;再次遇到值得记录的问题。 需求 项目前端使用vue框架&#xff0c;页面使用element-ui进行页面快速搭建。默认的table组件当表格过长时&#xff0c;下方会出现横向的滚动条&#xff0c;便于用户对表格进行左右滑动。考虑到页面美观问题&#xff0c;滚动条…...

【C++】list的使用(上)

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a; STL || C 目录 前言&#x1f308;关于list&#x1f525;默认成员函数构造函数&#xff08;constructor&#xff09;析构函数&#xff08;destructor&#xff09;赋值运算符重载 &#x1…...

【代码随想录训练营】【Day 37】【贪心-4】| Leetcode 840, 406, 452

【代码随想录训练营】【Day 37】【贪心-4】| Leetcode 840, 406, 452 需强化知识点 python list sort的高阶用法&#xff0c;两个key&#xff0c;另一种逆序写法python list insert的用法 题目 860. 柠檬水找零 思路&#xff1a;注意 20 块找零&#xff0c;可以找3张5块升…...

concat是什么?前端开发者必须掌握的数组拼接利器

concat是什么&#xff1f;前端开发者必须掌握的数组拼接利器 在前端开发中&#xff0c;concat是一个极其重要的概念&#xff0c;它能够帮助我们实现数组之间的无缝拼接。那么&#xff0c;concat到底是什么&#xff1f;为什么它在前端开发中如此重要&#xff1f;接下来&#xf…...

WHAT - 容器化系列(一)

这里写目录标题 一、什么是容器与虚拟机1.1 什么是容器1.2 容器的特点1.3 容器和虚拟机的区别虚拟机&#xff08;VM&#xff09;&#xff1a;基于硬件的资源隔离技术容器&#xff1a;基于操作系统的资源隔离技术对比总结应用场景 二、容器的实现原理1. Namespace&#xff08;命…...

QT7_视频知识点笔记_67_项目练习(页面以及对话框的切换,自定义数据类型,DB数据库类的自定义及使用)

视频项目&#xff1a;7----汽车销售管理系统&#xff08;登录&#xff0c;品牌车管理&#xff0c;新车入库&#xff0c;销售统计图表&#xff09;-----项目视频没有&#xff0c;代码也不全&#xff0c;更改项目练习&#xff1a;学生信息管理系统。 学生信息管理系统&#xff1…...

windows10系统64位安装delphiXE11.2完整教程

windows10系统64位安装delphiXE11.2完整教程 https://altd.embarcadero.com/download/radstudio/11.0/radstudio_11_106491a.iso XE11.1 https://altd.embarcadero.com/download/radstudio/11.0/RADStudio_11_2_10937a.iso XE11.2 关键使用文件在以下内容&#xff1a;windows10…...

09.责任链模式

09. 责任链模式 什么是责任链设计模式&#xff1f; 责任链设计模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;它允许将请求沿着处理者对象组成的链进行传递&#xff0c;直到有一个处理者对象能够处理该请求为止。这种模式的目的…...

Amazon云计算AWS(一)

目录 一、基础存储架构Dynamo&#xff08;一&#xff09;Dynamo概况&#xff08;二&#xff09;Dynamo架构的主要技术 二、弹性计算云EC2&#xff08;一&#xff09;EC2的基本架构&#xff08;二&#xff09;EC2的关键技术&#xff08;三&#xff09;EC2的安全及容错机制 提供的…...

十_信号4-SIGCHLD信号

SIGCHLD信号 在学习进程控制的时候&#xff0c;使用wait和waitpid系统调用何以回收僵尸进程&#xff0c;父进程可以阻塞等待&#xff0c;也可以非阻塞等待&#xff0c;采用轮询的方式不停查询子进程是否退出。 采用阻塞式等待&#xff0c;父进程就被阻塞了&#xff0c;什么都干…...

HCIP的学习(27)

RSTP—802.1W—快速生成树协议 STP缺陷&#xff1a; 1、收敛速度慢----STP的算法是一种被动的算法&#xff0c;依赖于计时器来进行状态变化 2、链路利用率低​ RSTP向下兼容STP协议。&#xff08;STP不兼容RSTP&#xff09; 改进点1—端口角色 802.1D协议---根端口、指定端口…...