Python面向对象浅析
目录
面向对象基本概念
一、类和对象
类和对象是面向对象骗程的两个核心概念。
在程序开发中,要设计一个类,通常需要满足一下三个要素:
self详解:
对象(Object)
魔法方法:
类里的一些特殊方法
__init__和__del__方法:
repr__和__str
运算符的相关魔法方法:
__eq__方法
类属性和对象属性
简单理解:类属性是整个类共有的属性,对象属性是每个对象实例的属性,类属性的值每个对象都一样,而对象属性的值每个对象各不相同。
私有属性和方法
获取私有属性的方法:
静态方法和类方法:
静态方法和类方法均可通过实例和类调用
单例模式
二、封装(Encapsulation)
三、继承(Inheritance)
父类中的私有方法和私有属性
四、多态(Polymorphism)
五、总结
面向对象基本概念
在编程领域,面向对象编程(OOP)是一种广泛使用的编程范式,它通过创建对象来模拟现实世界中的实体及其交互。Python作为一种高级编程语言,内置了对面向对象编程的全面支持,使得开发者能够轻松构建复杂且易于维护的应用程序。本文将详细探讨Python中的面向对象编程,包括类、对象、封装、继承和多态等核心概念。
一、类和对象
类(Class)
类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用.
类是创建对象的蓝图或模板,它定义了对象所具有的属性和方法。属性是对象的特征(如颜色、大小),而方法是对象能够执行的操作(如走、跑、叫)。
在程序开发中,要设计一个类,通常需要满足一下三个要素:
- 1.类名:这类事物的名字,按照大驼峰命名法(每个单词的首字母大写)起名。
- 2.属性:这类事物具有什么样的特征。
- 3.方法:这类事物具有什么样的行为。
class Dog: def __init__(self, name, age): self.name = name # 实例变量 self.age = age def bark(self): print(f"{self.name} is barking.")
在这个例子中,Dog
是一个类,它有两个实例变量name
和age
,以及一个方法bark
。__init__
方法是一个特殊的方法,被称为类的构造函数或初始化方法,当创建类的新实例时自动调用。
self详解:
哪个对象调用了方法,方法里的self 指的就是谁。通过self.属性名可以访问到这个对象的属性;通过self.方法名()可以调用这个对象的方法。
代码举例:
class Student(object):#这里的object表示Student继承自object类def __init__(self,x,y):self.name=xself.age=ydef say_hello(self):print('大家好,我是',self.name)
#Student('张三',18)这段代码具体做了什么呢?
#1.调用__new__方法,用来申请内存空间
#2.调用__init__方法传入参数,将self指向创建好的内存空间,填充数据
#3.变量s1也指向创建好的内存空间
s1=Student('张三',18)
s1.say_hello()
s2=Student('李四',18)
s2.say_hello()
结果:
大家好,我是 张三
大家好,我是 李四
对象(Object)
对象是类的实例。通过类可以创建多个具有相同属性和方法的对象,但每个对象的属性值可能不同。
d1 = Dog("Buddy", 3)
d2 = Dog("Max", 5) d1.bark() # 输出: Buddy is barking.
d2.bark() # 输出: Max is barking.
魔法方法:
# 特点:
#1.不需要手动调用,会在合适的时机自动调用#2、这些方法,都是使用开始,使用结束#3.方法名都是系统规定好的,在合适的时机自己调用
__init__和__del__方法:
__init__创建对象时会自动调用
__del__当对象被销毁时,会自动调用这个方法
class Person(object):def __init__(self,name,age):#在创建对象时,会自动调用这个方法print('__init__方法被调用了')self.name=nameself.age=agedef __del__(self):#当对象被销毁时会自动调用这个方法print('__del__方法被调用了')
p=Person('张三',18)
del p
结果:
__init__方法被调用了
__del__方法被调用了
repr__和__str
当打印一个对象时,会调用这个对象的__repr__或__str__方法,如果两个方法都写了则调用__str__方法
调用repr()方法,会调用对象的__repr__方法
class Person(object):def __init__(self,name,age):#在创建对象时,会自动调用这个方法print('__init__方法被调用了')self.name=nameself.age=agedef __del__(self):#当对象被销毁时会自动调用这个方法print('__del__方法被调用了')def __repr__(self):return 'repr'+self.name+' '+self.agedef __str__(self):return 'str'+self.name+' '+self.age
p=Person('张三','18')
print(p)
print(repr(p))
print(p.__repr__)
结果:
__init__方法被调用了
__del__方法被调用了
str张三 18
repr张三 18
<bound method Person.__repr__ of repr张三 18>
运算符的相关魔法方法:
==会调用对象的_eq_方法,获取这个方法的比较结果
__eq___如果不重写,默认比较依然是内存地址
class Person(object):def __init__(self,name,age):#在创建对象时,会自动调用这个方法self.name=nameself.age=agedef __eq__(self,other):return self.name==other.name and self.age==other.age
p1=Person('张三',18)
p2=Person('张三',18)
# p1和p2是同一个对象吗?
#怎样比较两个对象是否是同一个对象?比较的是内存地址
# is身份运算符可以用来判断两个对象是否是同一个对象
print(p1 is p2)# False
#is 比较两个对象的内存地址
# ==会调用对象的_eq_方法,获取这个方法的比较结果
nums1 = [1,2,3]
nums2 = [1,2,3]
print(nums1 is nums2)# False
print(nums1 == nums2)#True
#p1==p2本质是p1.eq(p2)获取这个方法的返回值
print(p1==p2)#true,因为在Person类中已经写了__eq__方法
结果:
False
False
True
True
__ne__方法
!=本质是调用__ne__方法或者__eq__方法取反__gt__方法
> 本质调用_ne__方法__ge__方法
> =本质调用__ge__方法…
__add__方法
+默认调用此方法__sub__方法
-默认调用此方法…
__str__方法
将对象转换为字符串时会调用此方法
打印对象时也会调用,默认是类型+内存地址
类属性和对象属性
简单理解:类属性是整个类共有的属性,对象属性是每个对象实例的属性,类属性的值每个对象都一样,而对象属性的值每个对象各不相同。
class Person(object):type='人类'def __init__(self,name,age):#在创建对象时,会自动调用这个方法self.name=nameself.age=age
#每个实例之间的属性没有关联,互不影响
p1=Person('张三',18)
p2=Person('李四',18)
#可以通过实例对象来获取类属性
print(p1.type)
print(p2.type)p1.type='human'
print(p1.type) #并不会修改类属性,而是给实例对象增加了一个属性#类属性只能通过类对象来修改,实例对象无法修改类属性
Person.type='monkey'# 修改了类属性print(p2.type)
print(Person.type)
结果:
人类
人类
human
monkey
monkey
私有属性和方法
不能够通过对象.属性(方法)的形式直接调用,会报错
以两个下划线开始的变量或方法为私有的
- 1.使用 对象._类名__私有变量名获取(也适用于私有方法)
- 2.定义get和set方法来获取
- 3.使用property来获取
私有方法可以在类中的其他方法中调用:
def __demo(self):#__开头的方法为私有方法,在外部不能直接调用print('我是私有方法')def test(self):self.__demo()
静态方法和类方法:
class Person(object):type='rich'def __init__(self,name,age):self.name=nameself.age=age#如果一个方法里没有用到对象属性和类属性则可定义为静态方法@staticmethoddef demo():print('hello')#类方法有一个参数cls,无需手动传参,指的是类对象,当前类中 cls is Person@classmethoddef test(cls):#print(cls.type)
p=Person('张三',18)
#静态方法和类方法均可以通过实例对象和类对象调用
p.demo()
Person.demo()
p.test()
Person.test()
结果:
hello
hello
rich
rich
单例模式
简单理解为一个类从始至终只有一个实例对象
class Singleton:__instance=None__is_first=True@classmethoddef __new__(cls,*args,**kwargs):if cls.__instance is None:cls.__instance=object.__new__(cls)return cls.__instancedef __init__(self,a,b):if self.__is_first:self.a=aself.b=bself.__is_first=False
s1=Singleton('哈哈','嘿嘿嘿')
s2=Singleton('呵呵','嘻嘻嘻')
print(s1.a)
print(s2.a)
结果:
哈哈
哈哈
二、封装(Encapsulation)
封装是面向对象编程的核心思想之一,它将对象的属性和方法封装成一个整体,隐藏对象的内部实现细节,只提供有限的对外接口。在Python中,虽然可以直接访问对象的属性,但通常建议通过方法(如getter
和setter
)来访问和修改属性,以维护封装性。
class Dog: def __init__(self, name, age): self._name = name # 使用单下划线表示受保护的属性(习惯用法,Python不强制) self._age = age def get_name(self): return self._name def set_name(self, name): self._name = name # ... 其他方法
三、继承(Inheritance)
继承允许我们定义一个类(子类)来继承另一个类(父类)的属性和方法。子类可以拥有父类的所有属性和方法,并且还可以定义自己的属性和方法。
class Animal: def __init__(self, name): self.name = name def speak(self): raise NotImplementedError("Subclass must implement abstract method") class Dog(Animal): def __init__(self, name, age): super().__init__(name) # 调用父类的__init__方法 self.age = age def speak(self): return f"{self.name} says Woof!" # 使用
d = Dog("Rex", 4)
print(d.speak()) # 输出: Rex says Woof!
在这个例子中,Dog
类继承了Animal
类,并实现了speak
方法。
多继承举例:
若一个子类继承了多个父类
例:class A(B,C),即A类同时继承了B、C两个父类,则调用子类的某个方法时,先在A类里面找,若A类没有则会去B类方法里面找,若B类里面也没有,继续找B的父类,若B的祖先类里都没有则回去C里面找,C里面没有去C的父类里面找…(广度搜索下深度搜索)
class Animal(object):#Animal继承自object类def __init__(self,name,age):self.name=namedef sleep(self):print(self.name+'正在睡觉')
class Dog(Animal,object):#Dog类继承自Animal类def bark(self):print(self.name+'正在叫')
d=Dog('小哈',3)
d.bark()
print(Dog.__mro__)
结果:
小哈正在叫
(<class '__main__.Dog'>, <class '__main__.Animal'>, <class 'object'>)
父类中的私有方法和私有属性
父类中的私有方法和属性不能继承
可以通过对象名._父类名__私有方法(或属性名进行调用)
class Animal(object):#Animal继承自object类def __init__(self,name,age):self.name=nameself.__age=agedef __sleep(self):print(self.name+'正在睡觉')
class Dog(Animal):#Dog类继承自Animal类def bark(self):print(self.name+'正在叫')
d=Dog('小哈 ',3)
print(d._Animal__age)
d._Animal__sleep()
结果:
3
小哈 正在睡觉
四、多态(Polymorphism)
多态允许不同类的对象对同一消息作出响应。在Python中,多态是隐式实现的,因为Python是动态类型语言。你可以定义一个接受任意类型对象作为参数的函数,并在这个函数中调用这些对象的方法,而不需要关心它们的具体类型。
def make_it_speak(animal): return animal.speak() # 假设还有其他类,如Cat,也实现了speak方法
class Cat(Animal): def speak(self): return f"{self.name} says Meow!" c = Cat("Whiskers")
print(make_it_speak(c)) # 输出: Whiskers says Meow!
在这个例子中,make_it_speak
函数可以接受任何具有speak
方法的对象作为参数,并调用该方法。
五、总结
面向对象编程为Python开发者提供了一种强大而灵活的方式来构建和维护复杂的软件系统。通过类、对象、封装、继承和多态等核心概念,开发者能够创建出高度模块化和可重用的代码,从而提高开发效率和软件质量。希望本文能够帮助到大家更好地理解和应用Python的面向对象编程。
本文灵感来自原文链接:https://blog.csdn.net/m0_46213598/article/details/119256595
相关文章:

Python面向对象浅析
目录 面向对象基本概念 一、类和对象 类和对象是面向对象骗程的两个核心概念。 在程序开发中,要设计一个类,通常需要满足一下三个要素: self详解: 对象(Object) 魔法方法: 类里的一些特殊方法 __in…...

JS基本语法
JS代码写在body结束标签的上面 如点击按钮调用方法: 在浏览器的控制台打印测试数据 console.log() <body><button type"button" onclick"easymethod()">点击我</button><script>//JS代码,写在body标签的…...

LSTM详解总结
LSTM(Long Short-Term Memory)是一种用于处理和预测时间序列数据的递归神经网络(RNN)的改进版本。其设计初衷是为了解决普通RNN在长序列训练中出现的梯度消失和梯度爆炸问题。以下是对LSTM的详细解释,包括原理、公式、…...

制品库nexus
详见:Sonatype Nexus Repository搭建与使用(详细教程3.70.1)-CSDN博客 注意事项: 1.java8环境使用nexus-3.69.0-02-java8-unix.tar.gz包 2.java11环境使用nexus-3.70.1-02-java11-unix.tar.gz包 3.注意使用制品库/etc/yum.repos.…...
2022.11.17 阿里钉钉数据开发岗位一面
今天晚上和阿里钉钉面试官聊了一面,整个过程持续45分钟,还是相当持久的。前面先让我自我介绍,包括自身背景、工作经历和项目经验,在介绍的时候面试官几次打断,让我停下来,然后他提问,我很纳闷还…...

【无标题】Git(仓库,分支,分支冲突)
Git 一种分布式版本控制系统,用于跟踪和管理代码的变更 一.Git的主要功能: 二.准备git机器 修改静态ip,主机名 三.git仓库的建立: 1.安装git [rootgit ~]# yum -y install git 2.创建一个…...

访问控制列表(ACL)
文章目录 ACL原理与基本配置ACL分类ACL组成ACL规则的匹配与应用 ACL原理与基本配置 ACL(Access Control List,访问控制列表) 读取二层、三层、四层报文信息根据预先定义好的规则对报文进行过滤和分类实现网络访问控制、防止网络攻击和提高网络带宽利用率等目的提高…...
自用git命令(待完善)
----------------------------------------------------------------------------------------- ###基础 git config --global user.name "xxxxx" #设置提交人 name git config --global user.email "xxxxxx163.com" #设置提交人 email git …...

突破•指针四
听说这是目录哦 函数指针数组🫧用途:转移表 回调函数🫧能量站😚 函数指针数组🫧 函数指针数组是存放函数地址的数组,例如int (*parr[5])()中parr先和[]结合,说明parr是可以存放5个函数地址【元…...
深入解析Python `requests`库源码,揭开HTTP请求的神秘面纱!
🔸 第一部分:requests库的入口 我们从requests库的入口开始,通常我们会使用 requests.get() 或 requests.post() 等方法发送HTTP请求。那么,这些方法背后究竟做了些什么呢?我们从requests.get()方法开始看起ÿ…...
day1 服务端与消息编码
文章目录 消息的序列化与反序列化通信过程服务端的实现main 函数(一个简易的客户端) 本文代码地址: 本文是7天用Go从零实现RPC框架GeeRPC的第一篇。 使用 encoding/gob 实现消息的编解码(序列化与反序列化)实现一个简易的服务端,仅接受消息,…...

部署WMS仓储管理系统项目后的注意事项
在探讨现代WMS仓储管理系统的部署与运营时,我们不得不深入剖析其背后的多维度考量与策略,以确保这一核心系统能够无缝融入并推动企业的整体供应链优化。WMS仓储管理系统作为连接仓库内部操作与外部供应链的桥梁,其重要性不言而喻,…...

跨网段 IP 地址通信故障分析
现如今计算机网络的规模和复杂性不断增加,跨网段通信成为网络运行中的常见需求。但如果设备处于不同网段且路由设置出现偏差时就会导致通信故障,严重影响网络的正常运行和数据传输。 1.跨网段通信的基本原理 跨网段通信依赖于路由器的路由功能。路由器根…...

存储引擎MySQL和InnoDB(数据库管理与高可用)
1、存储引擎 存储引擎是核心组成部分, 是构成数据库最基础最底层的部件, 利用这个部件,你的Mysql能够对数据进行查询、创建、更新、删除等操作, 也就是说,用户所输入的一系列的mysql语句,是由存储引擎来…...

探索局域网传输新境界 | 闪电藤 v2.2.7
在这个数字化时代,文件的快速、安全传输是我们日常工作中不可或缺的一部分。今天,电脑天空向大家介绍一款革命性的局域网文件传输工具——闪电藤,它将彻底改变你的文件传输体验。 🎨 界面设计 —— 极简之美 闪电藤采用极简的设…...
Tiling Window Management
我主要说一下windows版的 下面这个链接用的人比较多 GitHub - LGUG2Z/komorebi: A tiling window manager for Windows 🍉 建议搭配 GitHub - da-rth/yasb: A highly configurable cross-platform (Windows) status bar written in Python. GitHub - amnweb/ya…...
9. kubernetes资源——pv/pvc持久卷
kubernetes资源——pv/pvc持久卷 一、volume数据卷1、hostPath2、挂载nfs实现持久化 二、pv/pvc 持久卷/持久卷声明1、pv/pvc介绍2、pv/pvc的使用流程2.1 创建pv2.2 创建pvc2.3 创建pod,使用pv做持久化 一、volume数据卷 用于pod中的数据的持久化存储 支持很多的卷…...

2024西安铁一中集训DAY27 ---- 模拟赛((bfs,dp) + 整体二分 + 线段树合并 + (扫描线 + 线段树))
文章目录 前言时间安排及成绩题解A. 倒水(bfs dp)B. 让他们连通(整体二分 按秩合并并查集 / kruskal重构树)C. 通信网络(线段树合并 二分)D. 3SUM(扫描线 线段树) 前言 T1没做出…...

STM32F401VET6 PROTEUS8 ILI9341 驱动显示及仿真
stm32cubemx新建工程代码,并生成工程 设置gpio 设置SPI 其他的参考stm32默认设置 然后编辑驱动代码 ili9341.h #ifndef ILI9341_H #define ILI9341_H#include <stdbool.h> #include <stdint.h>#include "glcdfont.h" #include "stm32…...

抖音视频素材网站有哪些?非常好用的5个抖音视频素材库分享
在打造引人入胜的抖音视频时,选择高品质的视频素材至关重要。优选的素材不仅能够显著提升视频的吸引力,还能让你的作品在众多视频中突出重围。对于抖音创作者而言,让我们探索一些备受推崇的视频素材平台,帮助你制作出既专业又引人…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...