面向对象 元类 gil log 协程 垃圾回收 描述符 property
封装、继承、多态
当谈到封装、继承和多态时,通常是在面向对象编程 (OOP) 的上下文中讨论的。
封装 (Encapsulation) 示例:
class Person: def __init__(self, name, age): self.__name = name # 使用双下划线前缀将属性变为私有 self.__age = age
def get_name(self): return self.__name
def set_name(self, new_name): if len(new_name) > 0: self.__name = new_name
def get_age(self): return self.__age
def set_age(self, new_age): if new_age >= 0: self.__age = new_age
# 创建一个Person对象并访问属性
person = Person("Alice", 30)
print(person.get_name()) # 输出:Alice
person.set_age(32) # 设置年龄
print(person.get_age()) # 输出:32
在这个示例中,我们通过将属性标记为私有(使用双下划线前缀)来封装数据,并提供公共方法(get_name、set_name、get_age、set_age)来访问和修改这些属性。这样,我们可以控制属性的访问和修改,以确保数据的安全性。
使用面向对象来开发,示例代码如下:
- 类:理解为模板
- 对象:理解为实物
- 在使用面向过程编程时,当需要对数据处理时,需要考虑用哪个模板中哪个函数来进行操作,但是当用面向对象编程时,因为已经将数据存储到了这个独立的空间中,这个独立的空间(即对象)中通过一个特殊的变量(
__class__)能够获取到类(模板),而且这个类中的方法是有一定数量的,与此类无关的将不会出现在本类中,因此需要对数据处理时,可以很快速的定位到需要的方法是谁 这样更方便 - 全局变量是只能有1份的,多个函数需要多个备份时,往往需要利用其它的变量来进行储存;而通过封装 会将用来存储数据的这个变量 变为了对象中的一个“全局”变量,只要对象不一样那么这个变量就可以再有1份,所以这样更方便
- 代码划分更清晰
继承 (Inheritance) 示例:
class Animal: def __init__(self, name): self.name = name
def speak(self): pass
class Dog(Animal): def speak(self): return f"{self.name} 说:汪汪汪!"
class Cat(Animal): def speak(self): return f"{self.name} 说:喵喵喵!"
# 创建一个Dog对象和一个Cat对象,并调用speak方法
dog = Dog("旺财")
cat = Cat("小花")
print(dog.speak()) # 输出:旺财 说:汪汪汪!
print(cat.speak()) # 输出:小花 说:喵喵喵!
在这个示例中,我们定义了一个基类 Animal,然后创建了两个派生类 Dog 和 Cat,它们继承了 Animal 的属性和方法。每个派生类都可以覆盖基类的方法(例如 speak),以实现自己的行为。
- 能够提升代码的重用率,即开发一个类,可以在多个子功能中直接使用
- 继承能够有效的进行代码的管理,当某个类有问题只要修改这个类就行,而其继承这个类的子类往往不需要就修改
多态 (Polymorphism) 示例:
class Shape: def area(self): pass
class Circle(Shape): def __init__(self, radius): self.radius = radius
def area(self): return 3.14 * self.radius * self.radius
class Rectangle(Shape): def __init__(self, length, width): self.length = length self.width = width
def area(self): return self.length * self.width
# 创建一个Shape的列表,包含不同类型的图形对象
shapes = [Circle(5), Rectangle(4, 6), Circle(3)]
# 计算并输出每个图形的面积
for shape in shapes: print(f"面积:{shape.area()}")
在这个示例中,我们定义了一个基类 Shape,以及两个派生类 Circle 和 Rectangle,它们都具有一个名为 area 的方法。通过多态,我们可以在一个列表中存储不同类型的图形对象,然后通过统一的方法调用来计算它们的面积。这就是多态的核心思想,不同的对象可以对相同的方法做出不同的响应。
class MiniOS(object):"""MiniOS 操作系统类 """def __init__(self, name):self.name = nameself.apps = [] # 安装的应用程序名称列表def __str__(self):return "%s 安装的软件列表为 %s" % (self.name, str(self.apps))def install_app(self, app):# 判断是否已经安装了软件if app.name in self.apps:print("已经安装了 %s,无需再次安装" % app.name)else:app.install()self.apps.append(app.name)class App(object):def __init__(self, name, version, desc):self.name = nameself.version = versionself.desc = descdef __str__(self):return "%s 的当前版本是 %s - %s" % (self.name, self.version, self.desc)def install(self):print("将 %s [%s] 的执行程序复制到程序目录..." % (self.name, self.version))class PyCharm(App):passclass Chrome(App):def install(self):print("正在解压缩安装程序...")super().install()linux = MiniOS("Linux")
print(linux)pycharm = PyCharm("PyCharm", "1.0", "python 开发的 IDE 环境")
chrome = Chrome("Chrome", "2.0", "谷歌浏览器")
chrome2 = Chrome("Chrome2", "3.0", "古哥浏览器")linux.install_app(pycharm)
linux.install_app(chrome)
linux.install_app(chrome)
linux.install_app(chrome2)print(linux)Linux 安装的软件列表为 []
将 PyCharm [1.0] 的执行程序复制到程序目录...
正在解压缩安装程序...
将 Chrome [2.0] 的执行程序复制到程序目录...
已经安装了 Chrome,无需再次安装
正在解压缩安装程序...
将 Chrome2 [3.0] 的执行程序复制到程序目录...
Linux 安装的软件列表为 ['PyCharm', 'Chrome', 'Chrome2']
多态需要用到继承,重写,调用某个方法时,要看是父类创建的实例,还是子类创建的实例,实例不同调用的方法不同
关键点:
- 定义了一个基类App,它具有name、version、desc属性,以及一个install方法用于安装。
- 定义了两个子类PyCharm和Chrome,继承自App。
- Chrome类对install方法进行了重写,添加了自定义的安装逻辑。
- 在MainOS类中,通过install_app方法安装不同的App实例对象,调用其install方法。
- 对于同一个install_app方法,传入不同的类的实例,会调用各自类中不同的install实现。这就是多态。
- 多态允许我们基于同一接口编写可扩展和可维护的代码。子类可以改变父类的行为,同时保持接口一致。
所以多态的关键是:
- 有继承关系
- 子类覆盖父类方法
- 对不同子类实例调用相同的方法
这使得调用者可以一致地调用方法,而具体执行代码依赖于运行时对象的类型。这就是多态
-
面向过程开发,简单、开发前期快速,越往后越复杂,适合小工程
-
面向对象开发,复杂、开发前期较慢,越往后开发越方便,适合大工程
没有最好的开发模式,只有经过多多练习,见的多了,感受多了,自然也就能够在不同的任务、不同的工程,使用合适的方式进行开发
静态方法和类方法
类属性、实例属性
它们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,
-
实例属性属于对象
-
类属性属于类
class Province(object):# 类属性country = 'china'def __init__(self, name):# 实例属性self.name = name# 创建一个实例对象
obj = Province('shangdong')
# 直接访问实例属性
print(obj.name)
# 直接访问类属性
Province.country
由上述代码可以看出【实例属性需要通过对象来访问】【类属性通过类访问】,在使用上可以看出实例属性和类属性的归属是不同的。
其在内容的存储方式类似如下图:
由上图看出:
-
类属性在内存中只保存一份
-
实例属性在每个对象中都要保存一份
-
通过类创建实例对象时,如果每个对象需要具有相同名字的属性,那么就使用类属性,用一份既可
实例方法、静态方法和类方法
方法包括:实例方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
-
实例方法:由对象调用;至少一个self参数;执行实例方法时,自动将调用该方法的对象赋值给self;
-
类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类赋值给cls;
-
静态方法:由类调用;无默认参数;
class Foo(object):def __init__(self, name):self.name = namedef ord_func(self):""" 定义实例方法,至少有一个self参数 """# print(self.name)print('实例方法')@classmethoddef class_func(cls):""" 定义类方法,至少有一个cls参数 """print('类方法')@staticmethoddef static_func():""" 定义静态方法 ,无默认参数"""print('静态方法')f = Foo("china")
# 调用实例方法
f.ord_func()
# 调用类方法
Foo.class_func()
# 调用静态方法
Foo.static_func()
实例方法
类方法
静态方法
- 相同点:对于所有的方法而言,均属于类,所以 在内存中也只保存一份
- 不同点:方法调用者不同、调用方法时自动传入的参数不同。
# 实例方法
# self参数表示当前对象的实例
class Person:def __init__(self, name):self.name = namedef say_hello(self):print(f'Hello, my name is {self.name}')p = Person('John')
p.say_hello() # 调用实例方法,自动传递当前实例p作为self参数# 静态方法
# 使用@staticmethod装饰器声明,不需要默认的self参数
class Person:def __init__(self, name):self.name = name@staticmethoddef hello():print('Hello!')Person.hello() # 直接使用类名调用静态方法,不需要实例化# 类方法
# 使用@classmethod装饰器声明,默认参数cls代表当前类本身
class Person:count = 0 # 类属性def __init__(self, name):self.name =相关文章:
面向对象 元类 gil log 协程 垃圾回收 描述符 property
封装、继承、多态 当谈到封装、继承和多态时,通常是在面向对象编程 (OOP) 的上下文中讨论的。 封装 (Encapsulation) 示例: class Person: def __init__(self, name, age): self.__name = name # 使用双下划线前缀将属性变为私有 self.__age = age de…...
bibitem格式 添加参考文献
这次写论文时遇到一种bibitem格式的参考文献,latex中没有bib文件 分三步走 找到这篇文章的Bib Tex的引用,然后新建bib文件,命名为下图: 然后把Bib Tex引用的内容复制到上图的文件中,新建tex文件 内容为 \document…...
Leetcode 2934. Minimum Operations to Maximize Last Elements in Arrays
Leetcode 2934. Minimum Operations to Maximize Last Elements in Arrays 1. 解题思路2. 代码实现 题目链接:2934. Minimum Operations to Maximize Last Elements in Arrays 1. 解题思路 这一题思路上其实很简单,直接分情况考察一下最后一个元素交换…...
02:2440---时钟体系
目录 一:时钟控制 1:基本概念 2:时钟结构图 3:结构图分析 4:总线 5:寄存器 A:FCLK--MPLLCON B:HCLK和PCLK--CLKDIVN C:注意 二:上电复位 1:上电复位 2:时钟选择 三:代码 一:时钟控制 1:基本概念 S3C2440A中的时钟控制逻辑可以产生所需的时钟信号,包括C…...
SOEM源码解析——ecx_siiSM(读取SII的SM信息)
0 工具准备 1.SOEM-master-1.4.0源码1 ecx_siiSM函数总览 /** Get SM data from SII SM section in slave EEPROM.从SII的SM段获取SM信息* @param[in] context = context struct 句柄* @param[in] slave = slave number 从站序号* @param[out] SM = first SM str…...
【见缝插针】射击类游戏-微信小程序项目开发流程详解
还记得小时候玩过的见缝插针游戏吗,比一比看谁插得针比较多,可有趣了,当然了,通过它可以训练自己的手速反应,以及射击水平,把握时机,得分越高就越有成就感,相信小朋友们会喜欢它的&a…...
flutter开发实战-TweenSequence实现动画序列
flutter开发实战-TweenSequence实现动画序列 一、TweenSequence TweenSequence是允许创建一个Animation由一系列补间动画来确定值,每个TweenSequenceItem都有定义在动画的持续时间的权重确定动画间隔。 TweenSequence 动画组类TweenSequenceItem 用来定义每一个动…...
Flowable 外部表单
内置表单需要在每个节点中去配置,当如果多个节点使用同一套表单属性就要配置多次比较麻烦,修改的时候也要修改多次,外部表单可以定义一次,然后其它节点都去引用同一个表单属性。 外部表单需要定义一个.form后缀的文件。 外部表单…...
[mysql]索引优化-2
目录 一、分页查询优化1.根据自增且连续的主键排序的分页查询2.根据非主键字段排序的分页查询 二、Join关联查询优化1.嵌套循环连接 Nested-Loop Join(NLJ) 算法2.基于块的嵌套循环连接 Block Nested-Loop Join(BNL)算法 三、count(*)查询优化1.查询mysql自己维护的总行数2.sho…...
数据分析实战 | 泊松回归——航班数据分析
目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 八、模型评价 一、数据及分析对象 CSV文件:o-ring-erosion-only.csv 数据集链接:https://download.csdn.net/download/m0_7…...
Fliki AI:让视频创作更简单、更高效
在当今的数字时代,视频已经成为人们获取信息和娱乐的重要方式。无论是企业宣传、教育培训还是个人创作,视频都发挥着越来越重要的作用。然而,视频制作是一项复杂的工作,需要掌握一定的技能和经验。这对于初学者或没有专业视频制作…...
webGL编程指南 第五章 MultiTexture.html
我会持续更新关于wegl的编程指南中的代码。 当前的代码不会使用书中的缩写,每一步都是会展开写。希望能给后来学习的一些帮助 git代码地址 :空 上一章节中我们学习texParameteri的使用,这一章节中我们两个图片进行混合 <!DOCTYPE html> <htm…...
mysql8安装和驱动jar包下载
方式一:基于docker安装 下拉镜像 docker pull mysql:8.0.21 启动镜像 docker run -p 3307:3306 --name mysql -e MYSQL_ROOT_PASSWORDhadoop -d mysql:8.0.21 启动成功后,进入容器内部拷贝配置文件,到宿主主机 docker cp mysql:/etc/mysql…...
(SpringBoot)第五章:SpringBoot创建和使用
文章目录 一:Spring和SpringBoot(1)Spring已解决和未解决的问题(2)SpringBoot 二:Spring项目的创建(1)IDEA创建(2)网页端创建 三:项目目录介绍及运…...
Linux重定向
文章目录 1. 文件描述符分配规则2. 重定向接口dup2自定义shell重定向(补充) 3. 标准输出和标准错误4. 如何理解一切接文件 本章代码gitee地址:文件重定向 1. 文件描述符分配规则 文件描述符的分配规则是从0下标开始,寻址最小的没有使用的数组位置&#…...
Python之文件与文件夹操作及 pytest 测试习题
目录 1、文本文件读写基础。编写程序,在 当前目录下创建一个文本文件 test.txt,并向其中写入字符串 hello world。2、编写一个程序 demo.py,要求运行该程序后,生成 demo_new.py 文件,其中内容与demo.py 一样࿰…...
物联网:实现数据驱动决策,推动经济发展
开发物联网系统的意义主要体现在以下几个方面: 连接一切:物联网的目标是连接一切,将生活中的各种物理对象互联起来。通过物联网开发,我们可以实现各类设备的智能化,包括家居设备、交通工具、工业设备等。这将为人们提…...
Leetcode 2929. Distribute Candies Among Children II
Leetcode 2929. Distribute Candies Among Children II 1. 解题思路2. 代码实现 题目链接:2929. Distribute Candies Among Children II 1. 解题思路 这一题很惭愧,没能自力搞定,最后是看了大佬的思路之后才做出来的,唉…… 这…...
【面经】ES中分片是什么?副本是什么?
ES分片 分片是将一个索引切分为多个底层物理的Lucene索引,这些被切分出来的每个部分称为一个分片。 每个分片都是一个全功能且独立的索引,可由集群中的任何主机存储。 在创建索引时,用户可以指定其分片的数量。 默认情况下,每个索…...
【算法练习Day46】判断子序列不同的子序列
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 判断子序列不同的子序列总结…...
CC-Link IE转Modbus TCP集成实战:耐达讯自动化网关在五星级酒店节能改造中的应用
在工业自动化系统集成领域,异构网络的数据交互始终是一个核心痛点。控制层普遍采用高性能的CC-Link IE工业以太网,以确保高速、确定的实时通信;而设备层往往存在大量基于Modbus TCP协议的通用设备,如变频器、智能仪表和传感器。这…...
I.MX6ULL 裸机开发:SPI 总线与多点触摸屏驱动原理剖析
摘要 本文基于 I.MX6ULL 裸机开发实践,系统梳理了 SPI 串行外设接口的通信协议、ECSPI 控制器配置方法以及 ADXL345 三轴加速度传感器的驱动实现。同时,针对开发板搭载的 GT9147 多点电容触摸控制器,详细分析了其 I2C 通信机制、中断处理流程…...
VS2013创建首个C++程序教程
在 Visual Studio 2013 中创建并运行第一个 C 程序,主要涉及环境准备、项目创建、代码编写、编译与调试等核心步骤。以下将结合具体操作和代码示例进行详细说明。 1. 环境准备与项目创建 启动 VS2013:确保 Visual Studio 2013 已正确安装。启动后&…...
MySQL如何防止开发环境数据同步到生产_设置访问控制与网络隔离
开发能删表是因为权限未按库限定或实例混用,如测试库与生产库共用实例、bind-address0.0.0.0暴露端口、localhost连接绕过网络控制、主从配置不当致数据回流等。MySQL用户权限只给SELECT,为什么开发还能删表?权限配置不等于安全隔离。即使GRA…...
使用 SciPy 实现 NumPy 数组的重叠拼接与加权融合
本文介绍一种基于 scipy.linalg.block_diag 的通用方法,将两个二维数组按指定重叠宽度进行对齐拼接,并对重叠区域元素取平均值;支持稀疏结构延展,兼顾内存效率与数值精度。 本文介绍一种基于 scipy.linalg.block_diag 的通用…...
四步生图封神,GenEval从61%狂拉到92%,全面超越GPT-4o的TDM-R1模型来了
在大模型强化学习的热潮中,图像生成领域长期缺少一套真正适配少步模型的通用 RL 框架,而 TDM-R1 的出现,恰恰补上了这块关键拼图。超快速 AI 生图领域再破性能天花板!香港科技大学唐靖团队、香港科技大学(深圳分校&…...
揭秘AI大模型如何一键打造爆款短视频:从零到发布的实战指南
1. 为什么你需要AI大模型来制作短视频 最近两年,短视频内容爆发式增长,但创作门槛却越来越高。传统视频制作需要写脚本、找素材、剪辑配音,一套流程下来至少半天时间。我去年帮朋友做科普账号时,经常熬夜到凌晨两三点剪视频&#…...
Cocos Creator平台适配层框架设计
在 Cocos Creator 多平台开发中,平台抽象层不仅是架构设计问题,更是工程落地能力的体现。如果仅停留在概念层面,很容易流于形式。因此,本文在系统总结的基础上,结合实际代码示例,说明如何构建一个可落地的多…...
Ubuntu 20.04 + RTX 3050:手把手教你用TensorRT 10.8和C++部署YOLOv11(保姆级避坑指南)
Ubuntu 20.04 RTX 3050:手把手教你用TensorRT 10.8和C部署YOLOv11(保姆级避坑指南) 在计算机视觉领域,YOLO系列模型因其卓越的实时检测性能而广受欢迎。本文将带你从零开始,在Ubuntu 20.04系统上,利用RTX…...
苹果手机HEIC图片怎么转JPG?苹果用户必看的4种方法
一、为什么需要HEIC格式转换?1 HEIC格式的优势与局限HEIC(高效图像编码)是苹果在iOS 11系统中推出的新一代图像格式,采用HEVC编码技术,在相同画质下比传统JPG格式文件体积减少约50%。这意味着用iPhone拍摄的照片能节省…...
