python学习之【类和对象】

news2024/12/25 9:20:21

前言

五一快乐!
上一篇文章python学习——【第八弹】中,给大家介绍了python中的函数,这篇文章接着学习python中的类和对象

在这里插入图片描述

我们知道,python中一切皆对象。在这篇文章开始之前,我们先了解一下编程界的两大阵营——面向过程和面向对象
这两个术语我们一定没少听过,那么就简单介绍下什么是面向过程、面向对象,以及两者的区别与联系是什么。

面向过程

面向过程:事物比较简单,可以用线性的思维去解决;举个例子——假如我们的客人来家里做客,我们要请吃饭,想做一道拿手好菜应该分几步呢?我们用线性的思维去考虑,是不是应该分为买菜,洗菜,炒菜这三步呢,用流程图来表示:

在这里插入图片描述

面向对象

面向对象:事物比较复杂,使用简单的线性思维无法解释。
我们依然举请客吃饭的例子:如果客人来做客,我们恰好不会做饭,这时可以打开手机点餐APP,通过APP来选择需要点的餐,然后请快递小哥送餐:

在这里插入图片描述

区别和联系

通过这两个例子我们发现,面向过程我们需要按照步骤一步一步实现;而通过面向对象我们只需要创建一个包含实现指定功能和方法、具有指定属性的类,通过一个个实例化对象调用或者是直接用类来调用这些方法,就能帮助我们实现想要的效果。
在这里插入图片描述

面向过程的思维方式主要关注程序如何执行,而不是如何被组织和分隔为模块以进行更高层次的抽象和复用。因此,在微观操作方面,面向过程可能是最适合的方法,因为它强调了严格的顺序和流程控制。
但是,在实现整个程序的过程中,一些更高级的编程范例(如面向对象)可能更适合于模块化代码并提高代码可重用性和可维护性

其实我们在以往的python学习中就接触了很多方法,比如在学习列表中我们会用到append()方法去向列表中添加某一元素,这个appen()方法,就是在列表list类中的一个常用方法:
在这里插入图片描述在这里插入图片描述

类的组成与创建

类的组成

类的组成包括:类属性 实例方法 静态方法 类方法

类的创建

类的定义语法: class Class_name: 其中,Class_name是类的名称(类名),由一个或多个单词组成,每个单词首字母大写

class  Class_name:
	pass

实例对象的创建

一个类可以创建多个该类的实例对象,每个实例对象的属性值可以不同也可以相同,并且实例对象的权限是最大的创建完成实例对象,就可以通过这个实例对象调用实例方法或者类属性等。
实例对象的创建语法:实例对象名=类名(参数)
如果类内没有传递静态变量,这里实例对象的创建就不需要参数传递。(当实例对象被创建时,Python会自动为它分配空间,并调用类的__init__方法来执行初始化操作。如果没有定义传递参数,就不需要传递任何参数。)

class Student:
    pass
stu1=Student(参数1,参数2,参数3,。。。)
stu2=Student(参数1,参数2,参数3,。。。)
stuN=Student(参数1,参数2,参数3,。。。)

在这里插入图片描述

实例化对象的id值转换成十六进制和value值相同,这里:stu1id值:140203633998736 转换成十六进制等于 其value值 7f83b3ccfb90
stu1=Student(‘tom’,20) #在init方法中我们传入了name age两个参数,这里创建的实例对象的参数也是两个
print(id(stu1),type(stu1)) #140203633998736 <class ‘main.Student’>
print(stu1) #<main.Student object at 0x7f83b3ccfb90> id转换成十六进制和输出的stu1的值是相同的

类属性

类属性:类中方法外的变量都叫做类属性,类属性被该类的所有对象共享。
类属性的调用方法:
1:可以使用实例对象调用,语法是 实例对象名.属性

2:可以直接用类调用,语法是 类名.类属性

class Place:
    # 类属性
    place1='山东'
    place2='河南'
#pl1和pl2分别为该类的实例对象
pl1=Place()
pl2=Place()
print('----------类属性的使用------------------\n')
#实例对象调用
print('出生地1:',pl1.place1,id(pl1.place1))
print('出生地2:',pl1.place2,id(pl1.place2))
print('直接被类调用:',Place.place1,Place.place2)
'''
出生地1: 山东 140018104483248
出生地2: 河南 140018103789008
直接被类调用: 山东 河南
'''

print('\n----------在类外使用类改变类属性-------\n')
# 类属性:place1和place2  被该类的所有实例对象(这里是pl1和pl2)所共享,
#因此在类外将类属性改变后,用该类的所有实例对象调用该类属性时,类指针指向的地址都是类属性改变后的地址
Place.place1='河北'
print('出生地1:',pl1.place1,id(pl1.place1))
print('出生地2:',pl2.place1,id(pl2.place1))
'''
 出生地1: 河北 140314679194608
 出生地2: 河北 140314679194608
'''

我们看到在类外改变类属性后,利用实例对象再次调用这一类属性时,打印出来的是类属性改变后的值,我们来看一下内存图:

在这里插入图片描述
可以直观的看到,在每个实例对象中都存有一个类指针指向类,那么当我们改变某个类属性指向的地址时,实例对象调用该属性时打印出来的就是类属性改变后的内存地址。

类中的初始化方法

Python中的初始化方法是在创建对象时最先调用的一个方法,用于对对象的属性进行初始化。通常情况下,初始化方法被实现为 __ init__() 方法。它的格式是 def__init__(self):

其中,方法名是由init (initialize的缩写,初始化的意思)加左右两边的双下划线组成。
在进行初始化方法时,须要传入一个参数 self(self是约定俗成的变量名,用于表示实例对象本身。虽然可以选择其他名称作为self参数,一般遵循这个约定,以确保代码易于阅读和理解。), 在python的类中 self代表实例本身,具体来说,是该实例方法的内存地址;在类的方法中(如__ init__),第一个参数永远都是self,表示创建的类的实例本身,而不是类本身。
每当进行类的实例化时,初始化方法会被自动执行,举个例子:

在这里插入图片描述
可以看到:我们只是创建了一个实例对象,并没有调用 init 方法,它就自动执行了。利用这个特性,我们通常会在 初始化方法 里完成类属性初始值的设置。

class Student  :
    #类属性
    place='山东' 
    school='大学'
    # 初始化方法  
    def __init__(self,name,age):
        self.name=name #self.name  称为实例属性 进行一个赋值操作  将局部变量的name的值赋给实例属性
        self.age=age

我们在初始化方法中传入了name,age两个参数,这时它们还只是局部变量,要想能够被实例对象调用,需要在初始化方法中将局部变量分别赋给实例属性,这里的实例属性是self.name, 当然也可以是self.别名,只是我们习惯上用局部变量的名字,这样也具有一定的可读性。

当我们创建类的实例对象时传入了参数,那么就要在类体内进行初始化方法,并传入相关参数。

这里我们简单了解下python中得self参数:

1.self只有在类的方法中才会有 , 其他函数或方法是不必带self的。

2.在调用时不必传入相应的参数。

3.在类的方法中(如__init__)  , 第一参数永远是self , 表示创建的类实例本身 , 而不是类本身。

4.可以把对象的各种属性绑定到self。

5.self代表当前对象的地址。self能避免非限定调用造成的全局变量。

6.self不是python的关键字, 也可以用其他名称命名 , 但是为了规范和便于读者理解 ,  推荐使用self。

7:python中的self等价于C++中的self指针和Java、C#中的this参数。

8:如果不加self ,  表示是类的一个属性(可以通过"类名.变量名"的方式引用), 加了self表示是类的实例的一个属性(可以通过"实例名.变量名"的方式引用)

实例方法

在类中定义的函数叫做方法,相当于类外的函数,该方法可以具备一定的功能,调用后执行。
实例方法最大的特点就是,它最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)。

实例化方法的调用:

1:使用实例对象调用: 实例对象名.方法名()

2:使用类调用: 类名.实例方法名(实例对象名)

class Student:
    place='山东'  #类属性   直接写在类里的变量  叫做类属性
    school='大学'

    # 初始化方法
    def __init__(self,name,age):
        self.name=name
        self.age=age

# 实例方法  定义在类外面的函数叫做函数;定义在类里面的函数叫做方法
#  其中info()括号中可以不写东西,但是默认是存在self的,习惯上写上self
    def info(self):
        print('我的名字叫:',self.name,'年龄是:',self.age)
    def eat(self):
        print('吃东西')
    def drink():
        print('喝水')
# 创建实例对象
stu1=Student('tom',20)
 
print('\n----------------使用实例对象调用实例方法------------\n')

# 创建完成实例对象,就可以通过这个实例对象调用实例方法  对象名.方法名
stu1.eat()
stu1.info()
stu1.drink()
'''
吃东西
我的名字叫: tom 年龄是: 20
喝水
'''

print('\n-----------------通过Student类来调用实例方法-----------\n')
# 或者是通过Student类进行实例方法的调用    类名.方法名(对象名)
Student.eat(stu1)
Student.info(stu1)
Student.drink()
'''
吃东西
我的名字叫: tom 年龄是: 20
喝水
'''

如果在实例方法中没有写入任何参数时,在用类调用该实例方法时不需要传入实例对象;如果传入会抛出 TypeError: drink() takes 0 positional arguments but 1 was given 错误

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

类方法

类方法 :在类内使用装饰器 @classmethod 修饰的方法 ,使用类名直接访问。

Python 类方法和实例方法相似,它最少也要包含一个参数,只不过类方法中通常将其命名为 cls,Python 会自动将类本身绑定给 cls 参数(注意,绑定的不是类对象)。也就是说,我们在调用类方法时,无需显式为 cls 参数传参。

类方法的调用:

​1:使用类名: 类名.类方法名()

2:使用实例对象:实例对象名.类方法名()

# 类方法的使用
class Staff:
    # 类方法
    @classmethod
    def class_method(cls):
        print('我是一个类方法')
staff1=Staff()
staff2=Staff()
print('------------类方法的使用-----------\n')
Staff.class_method()
print('----------实例对象调用类方法------\n')
staff2.class_method()

在这里插入图片描述

如果没有 @classmethod,则 Python 解释器会将class_method() 方法认定为实例方法,而不是类方法。

在这里插入图片描述

静态方法

静态方法:其实就是我们学过的函数,和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中,即类体外。

静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定。也正因为如此,类的静态方法中无法调用任何类属性和类方法。

静态方法 :使用@staticmethod修饰的方法, 使用类名直接访问。

静态方法的调用:

1:使用类名: 类名.静态方法名()

2:使用实例对象:实例对象名.静态方法名()

# 静态方法的使用
class Workers:
    @staticmethod
    def static_method():#静态方法中没有默认参数
        print('我是一个静态方法')
worker1=Workers()
print('-----------使用类调用静态方法-----------\n')
Workers.static_method()
print("----------使用实例对象调用静态方法-----------\n")
worker1.static_method()

在这里插入图片描述

总结

在实际编程中,几乎不会用到类方法和静态方法,因为我们完全可以使用函数代替它们实现想要的功能,但在一些特殊的场景中(例如工厂模式中),还是会使用类方法和静态方法。

每篇一语

听一千遍别人的故事,不如做一件自己的事情。

如有不足,感谢指正!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[渗透教程]-004-长城防火墙GFW的原理

文章目录 1. baidu.com 请求过程2. GFW原理2.1 GFW拦截方法1:DNS渲染2.2 通过IP黑名单2.3 VPN阻断1. baidu.com 请求过程 家庭的路由器具备了交换机的功能.域名–>ip,优先检测本地的缓存,没有的话就查找DNS服务器,传输层对应该层的数据进行封装增加了端口的信息,网络层对传输…

[230502]英语阅读长难句分析|共6个

&#x1f363;五月份第二篇笔记&#x1f363; 40&#xff1a;0/3 41&#xff1a; 3/3 目录 题目 40-1 &#xff08;1&#xff09;句子结构分析 &#xff08;2&#xff09;生词 &#xff08;3&#xff09;原题 40-2 &#xff08;1&#xff09;句子结构分析 &#xff08;2&#…

2022年度项目管理软件排名揭晓:哪些软件在市场中脱颖而出?

在项目管理软件的选择过程中&#xff0c;用户会倾向于参考一些软件排名来辅助自己进行选择。软件排名方面推荐参考G2&#xff0c;一个国外的靠谱软件评测网站&#xff0c;类似于软件版的“大众点评”&#xff0c;软件评价来自于真实用户&#xff0c;网站通过多维度的算法&#…

springboot3+react18+ts实现一个点赞功能

前端&#xff1a;vitereact18tsantd 后端&#xff1a;springboot3.0.6mybatisplus 最终效果大致如下&#xff1a; 后端&#xff1a; 引入pom依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring…

PMP/高项 03-项目进度管理

项目进度管理 概念 项目进度管理&#xff08;Schedule Management) 项目进度管理又叫项目工期管理&#xff08;Duration Management)或项目的时间管理(Time Management) 是一种为管理项目按时完成项目所需的各个过程 进度管理过程 规划进度管理 定义活动 排列活动顺序 估算活…

jQuery -- 常用API(上)

1. jQuery选择器 1.1 jQuery基础选择器 原生 JS 获取元素方式很多&#xff0c;很杂&#xff0c;而且兼容性情况不一致&#xff0c;因此 jQuery 给我们做了封装&#xff0c;使获取元素统一标准。 语法&#xff1a;$(“选择器”) // 里面选择器直接写 CSS 选择器即可&#xff…

【毕业设计】基于springboot + vue微信小程序商城

目录 前言一、视频展示二、系统介绍三、项目地址四、运行环境五、创新点/亮点六、设计模块①前台②后台 七、系统功能模块结构图八、 准备阶段①使用真实支付②使用模拟支付九、使用说明十、登录后台十一、后台页面展示十二、微信小程序页面展示关于我 前言 【毕业设计】基于s…

IPsec中IKE与ISAKMP过程分析(快速模式-消息2)

IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息1&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息2&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息3&#xff09;_搞搞搞高傲的博客…

数据结构与算法基础(王卓)(31):折半插入排序、希尔排序

目录 折半插入排序 Project 1: 问题&#xff1a;缺少在插入元素之前的移动元素的操作 Project 2:&#xff08;最终成品、结果&#xff09; 希尔排序 Project 1:&#xff08;个人思路&#xff09; 标准答案&#xff1a;&#xff08;PPT答案&#xff09; 解释说明&#xff…

etcd的Watch原理

在 Kubernetes 中&#xff0c;各种各样的控制器实现了 Deployment、StatefulSet、Job 等功能强大的 Workload。控制器的核心思想是监听、比较资源实际状态与期望状态是否一致&#xff0c;若不一致则进行协调工作&#xff0c;使其最终一致。 那么当你修改一个 Deployment 的镜像…

数据结构篇三:双向循环链表

文章目录 前言双向链表的结构功能的解析及实现1. 双向链表的创建2. 创建头节点&#xff08;初始化&#xff09;3. 创建新结点4. 尾插5. 尾删6. 头插7. 头删8. 查找9. 在pos位置前插入10. 删除pos位置的结点11. 销毁 代码实现1.ListNode.h2. ListNode.c3. test.c 总结 前言 前面…

03-WAF绕过-漏洞利用之注入上传跨站等绕过

WAF绕过-漏洞利用之注入上传跨站等绕过 思维导图 一、sql注入绕过 使用sqlmap注入测试绕过 1.绕过cc流量 通过sqlmap对网站进行测试的时候&#xff0c;如果对方有cc流量防护&#xff0c;需要给sqlmap设置一个代理进行注入。 防cc拦截&#xff1a;修改user-agent头代理&…

ADB调试删除手机内置应用

前言 最近手机升级到了鸿蒙3系统&#xff0c;但是内置了两个输入法&#xff0c;我想删掉小艺输入法&#xff0c;于是就有了这篇记录。   本文在B站上ADB调试卸载应用的教程的基础上&#xff0c;去掉了内网穿透相关操作步骤。 前期准备 手机&#xff08;荣耀10青春版&#x…

3.4 只读存储器

学习目标&#xff1a; 学习只读存储器&#xff08;ROM&#xff09;的目标可以包括以下内容&#xff1a; 了解ROM的基本概念、分类以及适用场景。掌握ROM的电路原理、逻辑结构和读取方式。熟悉ROM的编程方式和编程工具。理解ROM与EPROM、EEPROM和闪存的区别和联系。了解ROM在计…

IPsec中IKE与ISAKMP过程分析(快速模式-消息1)

IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息1&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息2&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息3&#xff09;_搞搞搞高傲的博客…

[架构之路-181]-《软考-系统分析师》-19- 系统可靠性分析与设计 - 概览

前言&#xff1a; 可靠性工程是研究产品生命周期中故障的发生、发展规律&#xff0c;达到预防故障&#xff0c;消灭故 障&#xff0c;提高产品可用性的工程技术。 信息系统的可靠性是指系统在满足一定条件的应用环境中能够正常工作的能力&#xff0c;可以按一般工程系统的可靠性…

图像生成论文阅读:GLIDE算法笔记

标题&#xff1a;GLIDE: Towards Photorealistic Image Generation and Editing with Text-Guided Diffusion Models 会议&#xff1a;ICML2022 论文地址&#xff1a;https://proceedings.mlr.press/v162/nichol22a.html 官方代码&#xff1a;https://github.com/openai/glide-…

【算法】回文数

目录 一.回文数 二.求回文数&#xff08;10000以内&#xff09; 代码&#xff1a; 翻译&#xff1a; 调试&#xff1a; 三.判断回文数 代码&#xff1a; 调试&#xff1a; 一.回文数 "回文数"是一种数字。 如&#xff1a;12321, 这个数字正读是12321,倒读也是…

C++的类

文章目录 class定义类声明和定义不分离成员函数声明与定义的分离 类的访问限定符类的实例化类对象的大小this指针 引入&#xff1a;什么是类呢&#xff1f; 在C语言阶段,结构体成员只能是它的属性,这个结构体就相当于张三,小时候它只被赋予了名字,性别,家庭住址等属性,但是他没…

docker Mysql部署主从集群

目录 1 docker安装 2 docker mysql 安装配置 远程连接 2.0 配置 2.0.1 文件夹 配置 2.0.2 主库文件配置 my.cnf -> 主库 id 和 开启二进制日志 2.0.3 从库文件配置 -> 从库 id 2.1 mysql 主 -> 第一个端口号和从库不一样 2.1.1 docker run 主库 2.1.2 查看主…