python中的类与对象
前言
在Python中,类是一种用于创建新类型对象的结构,它允许我们将数据和功能(属性和方法)封装到一个单独的逻辑单元中。类可以被看作是创建对象(实例)的蓝图或模板。类(Class)和对象(Object)是面向对象编程(OOP)的核心概念。
概念
类(Class)
类是一个用于创建对象的模板或蓝图。它定义了一组属性和方法,这些属性和方法将被它创建的对象所共享。类本质上是一种数据结构,它封装了数据以及操作这些数据的函数。
- 属性:类中定义的变量。它们代表了该类所有对象共有的数据。
- 方法:类中定义的函数。它们用于描述该类所有对象共有行为或功能。
通过定义一个类,你实际上是在定义一种新类型的数据结构,这种结构包含了特定类型、对象所具有的属性、可以对这些属性执行哪些操作。
对象(Object)
对象是根据类被创建出来的实例。每个对象都拥有独立于其他对象的属性值集合,但所有对象都共享同一个方法集合(即那些在其对应类中被定义过)。简单来说:
- 每个实例或对象都拥有从相同模板或蓝图(即:class)继承而来但独立存在、可以各自不同状态信息。
- 实例化是根据类创建对象的过程
类与对象之间关系
- 类型与实例关系:从概念上讲,你可以把“class”看作“type”,把由此“type”生成出来具体存在事物看作“instance”。例如,“Dog”可以是一个表示所有狗通性特点模板名字;而你家那条叫做"Rex"具体小狗则可视作根据"Dog"模板生成出来、带有自己特定状态信息如年龄、品种等信息记录项事物。
- 共享与唯一性原则:所有由同一个class生成出来instances会共享该class定义的代码逻辑项,不随各自instance状态变化而变化;同时每个instance也会拥有属于自己唯一且可能随时间改变状态信息记录项。
- 继承性原则: 类之间可以通过继承机制分享通用代码逻辑项,并允许子级别class在保持父级别已经提供功能基础上添加或修改部分以满足更加具体需求场景使用要求。
类定义
一个基本的类定义包括关键字class
,后面跟着类名和冒号。在其下方缩进的代码块中,可以定义属性(变量)和方法(函数)。
要使用一个类,你需要根据该类创建对象。每个对象都会有自己独立的属性集合。
class MyClass:def __init__(self, value): # 特殊方法__init__用于初始化对象,构造器self.my_attribute = valuedef my_method(self):return self.my_attribute * 2# 实例化对象
obj = MyClass(99)
print(obj)
print(obj.my_method())
print(obj.my_attribute)# 直接修改对象的属性
obj.my_attribute = 100print(obj)
print(obj.my_method())
print(obj.my_attribute)
类的命名规范
-
驼峰命名法:Python中的类名通常使用驼峰命名法(CamelCase)。这意味着类名中每个单词的首字母都大写,而且单词之间不使用下划线分隔。例如,
MyClass
、DataProcessor
、CarEngine
。 -
描述性命名:类名应该简洁且富有描述性,清楚地表明类的用途或功能。例如,避免使用模糊的名称如
Foo
或Bar
,而应选择更具描述性的名称,如Customer
、EmailParser
。 -
避免缩写:尽量避免使用缩写,因为缩写可能会使代码的可读性降低。完整的单词能更好地表达类的意图和功能。
-
首字母大写:按照Python的约定,类名的首字母应该大写,即使它是一个缩写。例如,
URLParser
而不是urlParser
。 -
避免使用内置类型名称:避免使用像
str
、list
或dict
这样的Python内置类型名称作为类名,以免造成混淆。 -
命名长度:虽然没有硬性的长度限制,但一般推荐类名不要过长,以保持代码的清晰和易于维护。
特殊方法
Python提供了多个特殊方法(也称为魔术方法),它们由双下划线包围。这些特殊方法提供了与Python语言功能集成的方式。
初始化和构造
__init__(self, [...])
: 对象初始化方法,在创建新实例后被调用。__new__(cls, [...])
: 实际的对象构造函数,是一个静态方法,在__init__
之前被调用。
class TestClassMethod:# 定义变量,如果不赋值则必须指定类型# 但是类型注解 value_a: int 表示期望 value_a 是一个整数类型,但它并不会阻止你将其他类型赋给该属性。value_a: intvalue_b = "value_b"# 初始化方法def __init__(self, init_value: int): # 类型注解本身并不会强制变量类型,在运行时仍然可以给带有类型注解的变量赋予任何类型的值。print(f'初始化方法调用... init_value : {init_value}')# 如果不指定 self. 则为局部变量,无法在这里赋值# value_a = init_valueself.value_a = init_value# 实际的对象构造函数,是一个静态方法,在__init__之前被调用。# 在生产环境编写代码时通常不需要自己手动重写 __new__ 方法;除非你需要控制对象创建过程。对于大多数情况,默认行为已经足够。@staticmethod# 名为 __new__ 的实例方法并非特殊方法。特殊方法 __new__ 应当被定义为静态方法(使用装饰器 @staticmethod),或者更常见地作为类方法(使用装饰器 @classmethod)。def __new__(cls, *args, **kwargs):print(f'对象构造函数调用... cls : {cls}')return super(TestClassMethod, cls).__new__(cls)method = TestClassMethod(1)print(method.value_a)
# 虽然类中定义了类型为int,但是照常可以赋值字符串
method.value_a = 'aa'
print(method.value_a)print(method.value_b)print(dir(method))
表示和格式化
__repr__(self)
: 定义对象的“官方”字符串表示。__str__(self)
: 定义对象的“非正式”或可打印字符串表示。__format__(self, format_spec)
: 定义当使用format()
函数时对象的格式。
__repr__(self)
- 目的:创建一个代表对象的官方字符串表示形式。
- 调用时机:当你调用内置函数
repr()
时;当没有定义__str__
时,在使用print函数打印对象或者在解释器中直接输入变量名查看对象时;还有就是在调试过程中经常会看到这个表示。 - 特点:应该尽可能返回一个明确且不模糊的字符串表示形式,最好能够通过这个字符串来重新创建该对象。因此,通常返回值会看起来像是一个有效的Python表达式。
class Point:def __init__(self, x, y):self.x = xself.y = ydef __repr__(self):return f"Point({self.x}, {self.y})"
__str__(self)
- 目的:创建一个对用户友好(非技术用户)的字符串表示形式。
- 调用时机:当你使用内置函数
str()
或者使用print函数打印一个对象时。 - 特点:返回值应该是可读性强、信息友好型描述。
class Point:def __init__(self, x, y):self.x = xself.y = ydef __str__(self):return f"Point located at ({self.x}, {self.y})"
区别
虽然两者都提供了关于对象信息展示方式,但主要区别在于目标受众和它们各自所承担角色:
__repr__
: 面向开发者和调试器。其目标是明确无误地表达出如何构造出相同数据内容的新实例。__str__
: 面向最终用户。其目标是提供友好易懂且便于阅读理解信息。
如果只实现了其中之一,则未实现者将默认使用已实现者进行替代。如果都没有实现,则会默认使用继承自object类中相应方法。
建议至少定义一个__repr__()
方法,在大多数情况下它将足够用来输出有意义并可辨识资源信息,并作为后备方案以防未定义 __str__()
.
运算符重载(算术、比较运算符)
__add__(self, other)
: 加法运算符+
。__sub__(self, other)
: 减法运算符-
。__mul__(self, other)
: 乘法运算符*
。__truediv__(self, other)
: 真除法运算符/
.__floordiv__(self, other)
: 地板除法运算符//
.__mod__(self, other)
: 取模(余数)操作%
.__eq__(self, other)
: 等于操作=
.__ne__(self, other)
: 不等于操作不等于操作.
class TestClassMethod:value = 100def __add__(self, other):return self.value + otherdef __sub__(self, other):return self.value - otherdef __mul__(self, other):return self.value * otherdef __truediv__(self, other):return self.value / otherdef __floordiv__(self, other):return self.value // otherdef __mod__(self, other):return self.value % otherdef __eq__(self, other):return self.value == otherdef __ne__(self, other):return self.value != other# 大于def __gt__(self, other):return self.value > other# 大于等于def __ge__(self, other):return self.value >= other# 小于def __lt__(self, other):return self.value < other# 小于等于def __le__(self, other):return self.value <= othermethod = TestClassMethod()print(method + 100)
print(method - 100)
print(method * 100)
print(method / 100)
print(method // 100)
print(method % 100)
print(method == 100)
print(method != 100)
print(method > 100)
print(method >= 100)
print(method < 100)
print(method <= 100)
属性访问
属性访问相关的特殊方法可以帮助我们自定义属性的获取、设置和删除行为:
class TestClassMethod:def __getattr__(self, name):# 当尝试获取一个不存在的属性时调用print(f"【报错】!!尝试获取不存在的属性: {name} ")return '不存在的属性!'def __setattr__(self, name, value):# 当对属性赋值时调用print(f"调用赋值方法 {name} {value}")# self.name = value 不能这样赋值,会导致递归调用super().__setattr__(name, value)def __delattr__(self, name):# 当删除一个属性时调用print(f"调用删除属性的方法 {name} ")super().__delattr__(name)method = TestClassMethod()method.value = 1
print(method.value)
print(method.value2)
del method.value
类属性
在Python中,类的属性可以分为两种:类属性和实例属性。
类属性
- 类属性访问
- 类属性可以通过类名直接访问。
- 实例也可以访问类属性,但是如果实例具有与类属性同名的实例属性,则会优先访问实例属性。
- 修改类属性
- 通过类名修改类属性会影响到所有访问该属性的实例,因为它们共享同一个类变量。
- 如果通过实例修改看似“修改”了一个类变量(即
instance.attribute = value
),其实是在该实例中创建了一个同名的实例变量,并不会影响到其他实例或者是该变量在原来的那个class中。
类属性是属于类本身的变量,它被所有该类的实例共享。这意味着如果你修改了一个类的类属性,这个改变会影响到所有该类的实例。
class MyClass:class_attribute = 0# 修改类属性将影响所有实例
MyClass.class_attribute = 1instance1 = MyClass()
instance2 = MyClass()print(instance1.class_attribute) # 输出: 1
print(instance2.class_attribute) # 输出: 1
实例(对象)属性
实例属性是属于特定对象(即某个具体实例)的变量。每个对象都有自己独立的一套实例属性,修改一个对象的实例属性不会影响其他对象。
- 对象属性访问
- 对象属性只能通过实例对象访问。它们是绑定到特定实例的,因此每个实例都有自己独立的对象属性副本。
- 修改对象属性
- 对象属性的修改仅限于该特定实例。修改实例的属性不会影响到类的其他实例。
- 如果尝试通过实例修改一个不存在的属性,Python会自动在该实例上创建这个属性。
class MyClass:def __init__(self, value):self.instance_attribute = value# 每个对象都有自己独立的 instance_attribute 属性。
instance1 = MyClass(10)
instance2 = MyClass(20)print(instance1.instance_attribute) # 输出: 10
print(instance2.instance_attribute) # 输出: 20# 修改一个对象的 instance_attribute 不会影响另一个。
instance1.instance_attribute = 30print(instance1.instance_attribute) # 输出: 30
print(instance2.instance_attribute) # 输出: 20
属性引用和修改规则
- 类变量属于整个类,所有基于此类创建出来的对象共享这个变量。
- 如果需要对所有对象都生效地更改某个值,请操作这个值所属类上定义好了的那个变量。
- 对象属性是绑定到类的实例上的,因此它们对于每个实例来说都是唯一的。
- 修改一个实例的属性不会影响到其他实例。
- 通过实例可以访问类属性,但是如果实例有一个与类属性同名的对象属性,则访问的是对象属性,这体现了Python中的“名称遮蔽”特性。(在Python中,“名称遮蔽”(Name Shadowing)是指子作用域中的名称覆盖了外部作用域中相同名称的变量。这种特性在类属性与实例属性之间的交互中尤为常见。)
class TestClassModifyAttr:attribute = 0def __init__(self, value):self.attribute = value@propertydef test_method(self):"""当你尝试访问或者修改一个对象(即某个具体实例)上不存在但在其对应类型定义中存在作为`@property`装饰器修饰过得方法时,Python解释器将调用相应方法来处理此次访问或者修改行为。"""print("调用 test_method")a = TestClassModifyAttr(999)print(a.attribute)
print(a.test_method)# 如果你尝试访问或者修改一个不存在于任何地方(既不是该类型定义中也不是其基类型定义中)
# 且未通过`@property`装饰器修饰过得方法时,
# 则解释器将调用 `__getattr__()` 或 `__setattr__()` 特殊方法来处理此次访问或者修改行为。
print(a.test_method2)
相关文章:
python中的类与对象
前言 在Python中,类是一种用于创建新类型对象的结构,它允许我们将数据和功能(属性和方法)封装到一个单独的逻辑单元中。类可以被看作是创建对象(实例)的蓝图或模板。类(Class)和对象…...

sentry-cli - error: Failed to load .sentryclirc file from project path
Xcode 15.2 warning sentry-cli - error: Failed to load .sentryclirc file from project path (/Users/zhuhongwei/Desktop/pandabill/.sentryclirc)推荐一下刚上线的 App 熊猫小账本,里面有用到这篇博客讲的内容 熊猫小账本 一个简洁的记账 App,用于…...

回归预测 | Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测
回归预测 | Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测(完整源码和数据) …...
如何添加 Android Native 系统服务
如何添加 Android Native 系统服务 工作学习过程中,我们可能需要去阅读不同类型的 Native 系统服务,也有可能会自己去完成一个 Native 系统服务。无论哪种情况都需要我们了解基本的 Native 如何去添加。就像我们写 Android App 得先了解一下四大组件才行…...
【力扣】189.轮转数组
题目描述 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,6…...

C语言字符函数和字符串函数详解
Hello, 大家好,我是一代,今天给大家带来有关字符函数和字符串函数的有关知识 所属专栏:C语言 创作不易,望得到各位佬们的互三呦 一.字符函数 在C语言中有一些函数是专门为字符设计的,这些函数的使用都需要包含一个头文…...

【CKA模拟题】查询消耗CPU最多的Pod
题干 For this question, please set this context (In exam, diff cluster name) 对于此问题,请设置此上下文(在考试中,diff 集群名称) kubectl config use-context kubernetes-adminkubernetesFind the pod that consumes the …...

网络简略总结
目录 一、三次握手 四次挥手 1、三次握手:为了建立长链接进行交互即建立一个会话,使用http/https协议 2、四次挥手是一个断开连接释放服务器资源的过程 3、如果已经建立了连接,但是客户端突然出现故障了怎么办? 4、谁可以中断连接?客户端还是服务端还是都可以? 5、…...
如何处理错误情况
处理错误情况是确保自动窗帘系统稳定运行的重要一环。在编写代码时,你需要考虑可能发生的各种错误情况,并编写相应的错误处理代码。下面是一些处理错误情况的常见方法: (1)错误检测: 首先,你需要能够检测到错误的发生。…...
【Greenhills】MULTI IDE-GHS最新版本Compiler 23.5.4的兼容性问题
【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 关于GHS推出的最新编译器版本 Compiler 2023.5.4在GHS以前版本的MULTI IDE上面能否使用的问题 2、 问题场景 针对于,客户使用MULTI IDE 8.1.4以前的IDE版本,想要搭载使用最新版本的编译器…...

用连续自然数之和来表达整数 - 华为OD统一考试(C卷)
OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 一个整数可以由连续的自然数之和来表示。给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式。 输入描述 一个目标整数T (1 <=T<= 1000) 输出描述 该整数的所有表达式…...

SQLiteC/C++接口详细介绍之sqlite3类(十二)
返回目录:SQLite—免费开源数据库系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(十一) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(十三) 37.sqlite3_load_extension 用于在SQLit…...

linux系统--------------mysql数据库管理
目录 一、SQL语句 1.1SQL语言分类 1.2查看数据库信息 1.3登录到你想登录的库 1.4查看数据库中的表信息 1.5显示数据表的结构(字段) 1.5.1数据表的结构 1.5.2常用的数据类型: 二、关系型数据库的四种语言 2.1DDL:数据定义语言&am…...

网络——入门基础
目录 协议 网络协议 OSI七层模型 网络传输基本流程 网络传输流程图 局域网通信 数据包的封装和解包 广域网通信 网络地址管理 IP地址 MAC地址 协议 关于什么是局域网,什么是广域网,我这里就不过多赘述了,我们直接来谈一下什么…...

二、yocto 集成ros2(基于raspberrypi 4B)
yocto 集成ros2 yocto 集成ros21. 下载ros layer2. 编译集成ros3. 功能验证 yocto 集成ros2 本篇文章为基于raspberrypi 4B单板的yocto实战系列的第二篇文章。 一、yocto 编译raspberrypi 4B并启动 本节我们将ros2机器人操作系统移植到我们的yocto系统里面。 1. 下载ros laye…...

html--bug
文章目录 html html <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>老师</title><style>body {background-color: #008000;margin: 0px;cursor: none;overflow: hidden;}</style></head><bod…...

Java基础学习笔记三
环境变量CLASSPATH classpath环境变量是隶属于java语言的,不是windows操作系统的,和PATH环境变量完全不同classpath环境变量是给classloader(类加载器)指路的java A 。执行后,先启动JVM, JVM启动classload…...

Linux快速入门,上手开发 01.学习路线
少时曾许凌云志,当取世间第一流 再见少年拉满弓,不惧岁月不飓风 —— 24.3.20 1.Linux的发展历史 2.VM虚拟机的Linux初体验 3.图形化页面设置系统——快速上手 4.命令行操作——向专业前进 5.核心操作命令——必知必会(管理企业级权限/定位b…...
JSX return里面如何用if判断
在JSX中,由于不能直接使用传统的JavaScript if 语句,但可以通过条件渲染来实现类似的效果。以下是一些方法: 1. 三元运算符(Ternary Operator) 最简单的条件渲染方式是使用三元运算符: return (<div>{condition ? <ComponentIfTrue /> : <Com…...

Vulnhub靶机渗透:DC-7打靶记录
前言 自信自强,来自于不怕苦、不怕难的积淀。宝剑锋从磨砺出,梅花香自苦寒来;任何美好理想,都离不开筚路蓝缕、手胼足胝的艰苦奋斗! 靶场介绍 DC-7是一个初中级的靶场,需要具备以下前置知识:…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...