5 Python的面向对象编程
概述
在上一节,我们介绍了Python的函数,包括:函数的定义、函数的调用、参数的传递、lambda函数等内容。在本节中,我们将介绍Python的面向对象编程。面向对象编程(Object-Oriented Programming, 即OOP)是一种编程范型,它以对象为基础,将数据和操作封装在一个类(Class)中。在Python中,类是一种定义对象结构和行为的模板,而对象则是类的实例。类定义了一个新的类型,用于创建具有特定属性和方法的对象。类是面向对象编程的核心,它允许程序员使用对象来组织代码和复用代码。
类的定义
在Python中,类的基本语法如下:
class ClassName:# class attributeclass_variable = "class variable"def __init__(self, arg1, arg2):# instance variableself.instance_variable = arg1 + arg2# instance methoddef instance_method(self):print("I am an instance method")# class method@classmethoddef class_method(cls):print("I am a class method")# static method@staticmethoddef static_method():print("I am a static method")
下面逐一介绍上面示例代码中的各个元素。
class ClassName:这是类定义的开始,以class关键字作为开头,ClassName是要定义的类的名称;最后面是冒号,冒号后面的内容需要缩进。
class_variable = "class variable":这是类变量,它是一个在类中定义的全局变量,所有实例共享同一个变量。
def __init__(self, arg1, arg2):这是类的构造函数,当一个类实例被创建时会自动调用。在这个例子中,构造函数接受两个参数:arg1和arg2。self是对当前实例的引用,调用时不需要写,由系统自动填入。构造函数可以不带参数,也可以带一个或多个参数。
self.instance_variable = arg1 + arg2:这是一个实例变量,每个实例都有自己独立的实例变量。在这个例子中,实例变量是arg1和arg2的和。
def instance_method(self):这是一个实例方法,它需要一个实例作为其第一个参数(通常命名为self,也可以使用其他名称)。self是对当前实例的引用,调用时不需要写,由系统自动填入。
@classmethod:这是一个类方法装饰器,标识后面是一个类方法。它不需要实例作为其第一个参数,而是使用类名本身作为第一个参数(通常命名为cls,也可以使用其他名称)。cls是对当前类的引用,调用时不需要写,由系统自动填入。
@staticmethod:这是一个静态方法装饰器,标识后面是一个静态方法。它不需要实例或类作为其参数。
类的使用
定义好类之后,我们就可以实例化该类的对象,并调用其属性和方法了。
class Person:def __init__(self, name, age):self.name = nameself.age = agedef show_info(self):print(f'name is {self.name}, {self.age} years old')@staticmethoddef show_skill():print('walk, run, swim')# 创建一个Person类的实例
person1 = Person('xiaoxiao', 20)
# 访问实例变量,输出:xiaoxiao 20
print(person1.name, person1.age)
# 访问实例方法,输出:name is xiaoxiao, 20 years old
person1.show_info()
# 访问静态方法,输出:walk, run, swim
person1.show_skill()
Person.show_skill()
可以看到,访问实例变量和实例方法时,必须使用实例对象。访问静态方法时,既可以使用实例对象,也可以使用类名。
类的__init__方法是类的构造函数,当一个类实例被创建时会自动调用。同样的,类的__del__方法是类的析构函数,在释放实例对象时,也会被自动调用。
class Animal:def __init__(self, name):self.name = nameprint(f'animal {name} constructed')def __del__(self):print(f'animal {self.name} destructed')def show(self):print(f'{self.name} is preset')def test():animal = Animal('seagull')animal.show()''' test作用域结束时,animal会销毁,故依次输出:
animal seagull constructed
seagull is preset
animal seagull destructed
'''
test()
类变量和实例变量
类变量是在类的所有实例中共享的变量,这就意味着,如果你改变了一个类变量的值,那么这个改变将影响到类的所有实例。类变量在类定义时声明,通常在类的方法中使用。
class MyClass: # 类变量 class_variable = 0 def __init__(self, instance_variable): self.instance_variable = instance_variable MyClass.class_variable = self.instance_variable + 100 instance1 = MyClass(66)
# 输出:166
print(MyClass.class_variable)instance2 = MyClass(88)
# 均输出:188
print(MyClass.class_variable)
print(instance1.class_variable)
print(instance2.class_variable)
在上面的示例代码中,class_variable是一个类变量,它被所有实例共享。每次创建一个新的实例时,都会改变class_variable的值。因此,当创建了instance2并给它一个值为88的参数时,class_variable的值就从166变成了188。
实例变量是在类的每个实例中单独存储的变量,这就意味着,如果你改变了一个实例的状态,那么这个改变只影响那个特定的实例。实例变量在类的__init__方法中声明,通常在实例的方法中使用。
class MyClass:def __init__(self, instance_variable):# 实例变量self.instance_variable = instance_variable instance1 = MyClass(66)
# 输出:66
print(instance1.instance_variable)# 创建实例2
instance2 = MyClass(88)
# 输出:88
print(instance2.instance_variable)
# 输出:66
print(instance1.instance_variable)# 改变实例1的实例变量值
instance1.instance_variable = 100
# 输出:100
print(instance1.instance_variable)
# 输出:88
print(instance2.instance_variable)
在上面的示例代码中,instance_variable是一个实例变量,每个实例都有它自己的副本。当你改变instance1的 instance_variable值时,instance2的值不会受到影响。
在Python中,两个下划线开头的属性被声明为私有属性,不能在类的外部被使用或直接访问。否则,运行时会报AttributeError的错误信息。
class MyNumber:def __init__(self, value):self.__value = valuenum = MyNumber(66)
# 访问私有属性,运行时报错:'MyNumber' object has no attribute '__value'
print(num.__value)
实例方法、类方法和静态方法
实例方法是定义在类中的普通函数,它需要一个实例作为第一个参数(通常命名为self)。实例方法只能通过类的实例来调用,可以访问类变量和实例变量。
类方法是定义在类中的普通函数,它需要一个类作为第一个参数(通常命名为cls)。类方法可以通过类和类的实例来调用,只能访问类变量,不能访问实例变量。在定义类方法时,可以使用@classmethod装饰器进行声明。
静态方法是定义在类中的普通函数,它不需要任何参数(包括 self)。静态方法可以通过类和类的实例来调用,不可以访问类变量和实例变量。在定义静态方法时,可以使用@staticmethod装饰器进行声明。
class Person:# 类变量skills: ['walk', 'run', 'swim']def __init__(self, name, age):# 示例变量self.name = nameself.age = age# 实例方法,可以访问类变量和实例变量def show_info(self):print(f'name is {self.name}, {self.age} years old')print(self.skills)# 类方法,可以访问类变量@classmethoddef show_skill(cls):print(cls.skills)# 静态方法,不可以访问类变量和实例变量@staticmethoddef show_basic():print('a person here')
在Python中,两个下划线开头的方法被声明为私有方法,不能在类的外部被使用或直接访问。否则,运行时会报AttributeError的错误信息。
class MyNumber:def __init__(self, value):self.__value = valuedef __show(self):print(self.__value)num = MyNumber(66)
# 访问私有属性,运行时报错:'MyNumber' object has no attribute '__show'
num.__show()
与C++、Java等语言不同,Python不支持函数重载。当类的定义中有多个同名的函数时,将以最后一个声明的函数为准。
class MyNumber:def __init__(self, value):self.__value = valuedef show(self):print(self.__value)def show(self, a):print(self.__value, a)num = MyNumber(100)
num.show(66)
# 运行时报错:MyNumber.show() missing 1 required positional argument: 'a'
num.show()
类的运算符重载
可以通过定义特定方法来重载类对象的运算符,以下是一些常见的运算符重载方法。
__add__(self, other):重载加法运算符 +,用于实现两个对象的相加。
__sub__(self, other):重载减法运算符 -,用于实现两个对象的相减。
__mul__(self, other):重载乘法运算符 *,用于实现两个对象的相乘。
__truediv__(self, other):重载除法运算符 /,用于实现两个对象的相除。
__floordiv__(self, other):重载整数除法运算符 //,用于实现两个对象的整数相除。
__mod__(self, other):重载取模运算符 %,用于实现两个对象的取模运算。
__pow__(self, other):重载幂运算运算符 **,用于实现两个对象的幂运算。
__eq__(self, other):重载相等运算符 ==,用于判断两个对象是否相等。
__ne__(self, other):重载不等运算符 !=,用于判断两个对象是否不相等。
__lt__(self, other):重载小于运算符 <,用于判断两个对象是否小于。
__le__(self, other):重载小于等于运算符 <=,用于判断两个对象是否小于等于。
__gt__(self, other):重载大于运算符 >,用于判断两个对象是否大于。
__ge__(self, other):重载大于等于运算符 >=,用于判断两个对象是否大于等于。
假如我们定义了一个名为MyNumber的类,可以按照以下方式重载加法运算符。
class MyNumber:def __init__(self, value):self.value = valuedef __add__(self, other):if isinstance(other, MyNumber):return MyNumber(self.value + other.value)return MyNumber(self.value + other)num1 = MyNumber(100)
num2 = MyNumber(200)
num = num1 + num2
# 输出:300
print(num.value)
继承
继承是一种实现面向对象编程的重要机制,它允许我们基于已有的类创建新的类,从而继承已有类的属性和方法。在Python中,使用class语句定义一个类时,可以在类名后面使用(base_classes)的形式指定该类要继承的父类。base_classes可以为一个类,也可以为多个类。多个类时,各个类之间用逗号进行分隔,属于多重继承的内容。
class Animal:def __init__(self, name):self.name = namedef eat(self):print(self.name + " is eating...")class Dog(Animal):def __init__(self, name, breed):super().__init__(name)self.breed = breeddog = Dog('Sky', 'Corgi')
# 输出:Sky is eating...
dog.eat()
# 输出:Corgi
print(dog.breed)
在上面的示例代码中,Dog类继承了Animal类,因此Dog类具有了Animal类的属性和方法。在Dog类的定义中,我们可以通过调用super().__init__(name)来调用父类的构造函数,从而初始化Dog类实例的name属性。
除了继承父类的属性和方法,子类还可以重写父类的方法,从而实现对父类行为的修改。
class Animal:def __init__(self, name):self.name = namedef eat(self):print(self.name + " is eating...")class Dog(Animal):def __init__(self, name, breed):super().__init__(name)self.breed = breeddef eat(self):print(self.breed + " eats more")dog = Dog('Sky', 'Corgi')
# 覆盖父类方法,输出:Corgi eats more
dog.eat()
# 强制调用父类方法,输出:Sky is eating...
super(Dog, dog).eat()
在上面的示例代码中,我们直接在Dog类中定义了一个与父类同名的eat方法,从而完全覆盖了父类的行为。如果想强制调用父类的方法,可以使用类似super(Dog, dog)的方式获得父类的实例,再调用父类的方法。
相关文章:
5 Python的面向对象编程
概述 在上一节,我们介绍了Python的函数,包括:函数的定义、函数的调用、参数的传递、lambda函数等内容。在本节中,我们将介绍Python的面向对象编程。面向对象编程(Object-Oriented Programming, 即OOP)是一种…...

卷积神经网络——上篇【深度学习】【PyTorch】【d2l】
文章目录 5、卷积神经网络5.1、卷积5.1.1、理论部分5.1.2、代码实现5.1.3、边缘检测 5.2、填充和步幅5.2.1、理论部分5.2.2、代码实现 5.3、多输入多输出通道5.3.1、理论部分5.3.2、代码实现 5.4、池化层 | 汇聚层5.4.1、理论部分5.4.2、代码实现 5、卷积神经网络 5.1、卷积 …...
【从零学习python 】54. 内存中写入数据
文章目录 内存中写入数据StringIOBytesIO进阶案例 内存中写入数据 除了将数据写入到一个文件以外,我们还可以使用代码,将数据暂时写入到内存里,可以理解为数据缓冲区。Python中提供了StringIO和BytesIO这两个类将字符串数据和二进制数据写入…...

速通蓝桥杯嵌入式省一教程:(九)AT24C02芯片(E2PROM存储器)读写操作与I2C协议
AT24C02芯片(又叫E2PROM存储器、EEPROM存储器),是一种通过I2C(IIC)协议通信的掉电保存存储器芯片,其内部含有256个8位字节。在介绍这款芯片之前,我们先来粗略了解一下I2C协议。 I2C总线是一种双向二线制的同步串行总线…...
负载均衡:优化性能与可靠性的关键
在现代互联网时代,数以万计的用户访问着各种在线服务,从即时通讯、社交媒体到电子商务和媒体流媒体,无不需要应对海量的请求和数据传输。在这个高并发的环境下,负载均衡成为了关键的技术,它旨在分散工作负载࿰…...

T113-S3-TCA6424-gpio扩展芯片调试
目录 前言 一、TCA6424介绍 二、原理图连接 三、设备树配置 四、内核配置 五、gpio操作 总结 前言 TCA6424是一款常用的GPIO(通用输入输出)扩展芯片,可以扩展微控制器的IO口数量。在T113-S3平台上,使用TCA6424作为GPIO扩展芯…...

奥威BI数据可视化工具:个性化定制,打造独特大屏
每个人都有自己独特的审美,因此即使是做可视化大屏,也有很多人希望做出不一样的报表,用以缓解审美疲劳的同时提高报表浏览效率。因此这也催生出了数据可视化工具的个性化可视化大屏制作需求。 奥威BI数据可视化工具:个性化定制&a…...
13 秒插入 30 万条数据,批量插入!
数据库表 CREATE TABLE t_user (id int(11) NOT NULL AUTO_INCREMENT COMMENT 用户id,username varchar(64) DEFAULT NULL COMMENT 用户名称,age int(4) DEFAULT NULL COMMENT 年龄,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8 COMMENT用户信息表; User实体 /*** …...

Nginx代理转发地址不正确问题
使用ngix前缀去代理转发一个地址,貌似成功了,但是进不到正确的页面,能够访问,但是一直404远处出来nginx会自动拼接地址在后面 后面才知道要将这段代码加上去,去除前缀转发...

HyperMotion高度自动化云迁移至华为HCS8.1解决方案
项目背景 2020 年以来,金融证券已经成为信创落地最快的领域。2021 年证监会发布的《证券期货业科技发展十四五规划》中,将“加强信创规划与实施”作为证券行业重点建设任务之一。为了符合国家信创标准,某证券企业计划将网管系统、呼叫中心管…...

pbootcms系统安全防护设置大全
PbootCMS系统简介 PbootCMS是全新内核且永久开源免费的PHP企业网站开发建设管理系统,是一套高效、简洁、 强悍的可免费商用的PHP CMS源码,能够满足各类企业网站开发建设的需要。系统采用简单到想哭的模板标签,只要懂HTML就可快速开发企业网站…...
【环境】docker时间与宿主同步
1.容器创建后 docker cp /etc/localtime 容器名:/etc/2.容器创建时 加入 -v /ect/localtime/:/etc/localtime:ro参考链接...
亮点!视频云存储/安防监控视频智能分析平台睡岗离岗检测
在生产过程中,未经领导允许的擅自离岗、睡岗会带来很多的潜在危害。TSINGSEE青犀推出的视频云存储/安防监控视频智能分析平台得睡岗离岗检测根据AI视频分析技术建立人工智能算法,对视频画面展开分析与识别。自动识别出人员睡岗、离岗、玩手机与抽烟等动作…...

编程锦囊妙计——快速创建本地Mock服务
点击上方👆蓝色“Agilean”,发现更多精彩。 前情提要 在本系列上一篇文章《全文干货:打破前后端数据传递鸿沟,高效联调秘笈》中我们分享了使用Zod这一运行时类型校验库来对后端服务响应结果进行验证达到增加项目质量的方式。 这次…...

简单认识镜像底层原理详解和基于Docker file创建镜像
文章目录 一、镜像底层原理1.联合文件系统(UnionFS)2.镜像加载原理3.为什么Docker里的centos的大小才200M? 二、Dockerfile1.简介2.Dockerfile操作常用命令 三、创建Docker镜像1.基于已有镜像创建2.基于本地模板创建3.基于Dockerfile创建4.Dockerfile多阶段构建镜像 一、镜像底…...

加速乐(__jsl_clearance_s)动态cookie生成分析实战
文章目录 一、写在前面二、抓包分析三、逆向分析 一、写在前面 加速乐(JSL)是阿里推出的一项反爬虫服务,其生成cookie的原理基于浏览器的行为特征 我们知道普通网站生成cookie是在请求时生成,而它先生成cookie,然后向服…...

启动Vue项目踩坑记录
前言 在启动自己的Vue项目时,遇到一些报错,当时很懵,解决了以后豁然开朗,特写此博客记录一下。 一、<template>里多加了个div标签 [vite] Internal server error: At least one <template> or <script> is req…...
vue-pc上传优化-uni-app上传优化
vue-pc上传优化 当我们使用自己搭建的文档服务器上传图片时候,在本地没问题,上线上传会比较慢 这时候我们最简单的方法就是写一个加载组件,上传之前打开组件,掉完接口关闭组件 或者不想写直接使用element的loading写一个遮罩层加…...

【计算机视觉|生成对抗】StackGAN:使用堆叠生成对抗网络进行文本到照片逼真图像合成
本系列博文为深度学习/计算机视觉论文笔记,转载请注明出处 标题:StackGAN: Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks 链接:[1612.03242] StackGAN: Text to Photo-realistic Image Synthesis…...

跟随角色镜头时,解决地图黑线/白线缝隙的三种方案
下面一共三个解决方案,这里我推荐第二个方案解决,因为够快速和简单。 现象: 解决方案一: 参考【Unity2D】去除地图中的黑线_unity选中后有线_香菇CST的博客-CSDN博客,博主解释是因为抗锯齿采样导致的问题。 具体到这…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...