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是一个初中级的靶场,需要具备以下前置知识:…...
5秒极速转换:让B站缓存视频重获新生的开源神器
5秒极速转换:让B站缓存视频重获新生的开源神器 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾经为那些"消失"的B…...
告别复制粘贴!用这个开源工具,5分钟把Swagger接口文档转成Word/Excel表格
5分钟极速转换:Swagger接口文档智能生成Word/Excel全攻略 每次项目交付前,团队里总有人对着Swagger UI疯狂截图,再粘贴到Word里调整格式到凌晨三点——这种场景你一定不陌生。其实早在2017年GitHub上就出现了首个Swagger转表格工具࿰…...
如何永久备份微信聊天记录:WeChatExporter终极指南
如何永久备份微信聊天记录:WeChatExporter终极指南 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾因手机丢失、系统升级或误操作而丢失了珍贵的微信…...
ncmdump终极指南:三分钟解锁网易云音乐加密文件,重获音乐自由
ncmdump终极指南:三分钟解锁网易云音乐加密文件,重获音乐自由 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为下载的网易云音乐只能在官方客户端播放而苦恼吗?ncmdump正是您需要的音乐解放工…...
Z-Image-Turbo_Sugar脸部Lora与Dify工作流引擎集成:打造无代码AI人脸风格化应用
Z-Image-Turbo_Sugar脸部Lora与Dify工作流引擎集成:打造无代码AI人脸风格化应用 想象一下,运营团队想为即将到来的春节活动,快速上线一个“生成你的专属国风头像”的小程序。按照传统流程,你需要召集前后端开发、算法工程师&…...
Dev-C++双人小游戏避坑指南:地图设计、碰撞检测与蹦床逻辑详解
Dev-C双人小游戏避坑指南:地图设计、碰撞检测与蹦床逻辑详解 在控制台环境下开发双人跑酷游戏,看似简单却暗藏玄机。许多开发者第一次尝试时,往往会被地图管理、角色交互和特殊效果实现这三个环节卡住。本文将分享我在Dev-C环境下开发这类游戏…...
生成代码没有单元测试?错!用Mutation Testing反向驱动AI补全——1套DSL规则让LLM自动生成带边界覆盖的测试桩(稀缺开源工具首发)
第一章:智能代码生成与代码度量结合 2026奇点智能技术大会(https://ml-summit.org) 智能代码生成已从简单补全迈向上下文感知的语义级产出,而代码度量则为生成结果提供了可量化、可追溯的质量锚点。二者融合并非功能叠加,而是构建“生成—评…...
UnrealPakViewer终极指南:5分钟掌握UE4 Pak文件分析的免费神器
UnrealPakViewer终极指南:5分钟掌握UE4 Pak文件分析的免费神器 【免费下载链接】UnrealPakViewer 查看 UE4 Pak 文件的图形化工具,支持 UE4 pak/ucas 文件 项目地址: https://gitcode.com/gh_mirrors/un/UnrealPakViewer 你是否曾被UE4项目中庞大…...
PHP与Suno音乐生成AI集成开发音频应用【操作】
PHP调用Suno API必须用cURL:需POSTBearer认证、硬截prompt至200字符、轮询时指数退避、流式下载音频并校验URL,audio_url有效期仅24小时。PHP调用Suno API必须用cURL,不能用file_get_contentsSuno官方API不支持HTTP GET直接拉取音频ÿ…...
【Emoji应用指南:从代码到文案的创意表达】
1. Emoji的前世今生:从键盘符号到全球语言 2008年,日本电信运营商NTT Docomo的设计师栗田穰崇创造了世界上第一套176个Emoji字符。当时谁也没想到,这些小小的彩色图标会在十几年后成为全球通用的数字语言。如今Unicode标准已经收录了超过3600…...
