当前位置: 首页 > news >正文

python中的类与对象

前言

在Python中,类是一种用于创建新类型对象的结构,它允许我们将数据和功能(属性和方法)封装到一个单独的逻辑单元中。类可以被看作是创建对象(实例)的蓝图或模板。类(Class)和对象(Object)是面向对象编程(OOP)的核心概念。

概念

类(Class)

类是一个用于创建对象的模板或蓝图。它定义了一组属性和方法,这些属性和方法将被它创建的对象所共享。类本质上是一种数据结构,它封装了数据以及操作这些数据的函数。

  • 属性:类中定义的变量。它们代表了该类所有对象共有的数据。
  • 方法:类中定义的函数。它们用于描述该类所有对象共有行为或功能。

通过定义一个类,你实际上是在定义一种新类型的数据结构,这种结构包含了特定类型、对象所具有的属性、可以对这些属性执行哪些操作。

对象(Object)

对象是根据类被创建出来的实例。每个对象都拥有独立于其他对象的属性值集合,但所有对象都共享同一个方法集合(即那些在其对应类中被定义过)。简单来说:

  • 每个实例对象都拥有从相同模板或蓝图(即:class)继承而来但独立存在、可以各自不同状态信息。
  • 实例化是根据类创建对象的过程

类与对象之间关系

  1. 类型与实例关系:从概念上讲,你可以把“class”看作“type”,把由此“type”生成出来具体存在事物看作“instance”。例如,“Dog”可以是一个表示所有狗通性特点模板名字;而你家那条叫做"Rex"具体小狗则可视作根据"Dog"模板生成出来、带有自己特定状态信息如年龄、品种等信息记录项事物。
  2. 共享与唯一性原则:所有由同一个class生成出来instances会共享该class定义的代码逻辑项,不随各自instance状态变化而变化;同时每个instance也会拥有属于自己唯一且可能随时间改变状态信息记录项。
  3. 继承性原则: 类之间可以通过继承机制分享通用代码逻辑项,并允许子级别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)

类的命名规范

  1. 驼峰命名法:Python中的类名通常使用驼峰命名法(CamelCase)。这意味着类名中每个单词的首字母都大写,而且单词之间不使用下划线分隔。例如,MyClassDataProcessorCarEngine

  2. 描述性命名:类名应该简洁且富有描述性,清楚地表明类的用途或功能。例如,避免使用模糊的名称如FooBar,而应选择更具描述性的名称,如CustomerEmailParser

  3. 避免缩写:尽量避免使用缩写,因为缩写可能会使代码的可读性降低。完整的单词能更好地表达类的意图和功能。

  4. 首字母大写:按照Python的约定,类名的首字母应该大写,即使它是一个缩写。例如,URLParser而不是urlParser

  5. 避免使用内置类型名称:避免使用像strlistdict这样的Python内置类型名称作为类名,以免造成混淆。

  6. 命名长度:虽然没有硬性的长度限制,但一般推荐类名不要过长,以保持代码的清晰和易于维护。

特殊方法

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中,类的属性可以分为两种:类属性和实例属性。

类属性

  1. 类属性访问
    • 类属性可以通过类名直接访问。
    • 实例也可以访问类属性,但是如果实例具有与类属性同名的实例属性,则会优先访问实例属性。
  2. 修改类属性
    • 通过类名修改类属性会影响到所有访问该属性的实例,因为它们共享同一个类变量。
    • 如果通过实例修改看似“修改”了一个类变量(即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

实例(对象)属性

实例属性是属于特定对象(即某个具体实例)的变量。每个对象都有自己独立的一套实例属性,修改一个对象的实例属性不会影响其他对象。

  1. 对象属性访问
    • 对象属性只能通过实例对象访问。它们是绑定到特定实例的,因此每个实例都有自己独立的对象属性副本。
  2. 修改对象属性
    • 对象属性的修改仅限于该特定实例。修改实例的属性不会影响到类的其他实例。
    • 如果尝试通过实例修改一个不存在的属性,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中&#xff0c;类是一种用于创建新类型对象的结构&#xff0c;它允许我们将数据和功能&#xff08;属性和方法&#xff09;封装到一个单独的逻辑单元中。类可以被看作是创建对象&#xff08;实例&#xff09;的蓝图或模板。类&#xff08;Class&#xff09;和对象…...

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 熊猫小账本&#xff0c;里面有用到这篇博客讲的内容 熊猫小账本 一个简洁的记账 App&#xff0c;用于…...

回归预测 | Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测&#xff08;完整源码和数据) …...

如何添加 Android Native 系统服务

如何添加 Android Native 系统服务 工作学习过程中&#xff0c;我们可能需要去阅读不同类型的 Native 系统服务&#xff0c;也有可能会自己去完成一个 Native 系统服务。无论哪种情况都需要我们了解基本的 Native 如何去添加。就像我们写 Android App 得先了解一下四大组件才行…...

【力扣】189.轮转数组

题目描述 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 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, 大家好&#xff0c;我是一代&#xff0c;今天给大家带来有关字符函数和字符串函数的有关知识 所属专栏&#xff1a;C语言 创作不易&#xff0c;望得到各位佬们的互三呦 一.字符函数 在C语言中有一些函数是专门为字符设计的&#xff0c;这些函数的使用都需要包含一个头文…...

【CKA模拟题】查询消耗CPU最多的Pod

题干 For this question, please set this context (In exam, diff cluster name) 对于此问题&#xff0c;请设置此上下文&#xff08;在考试中&#xff0c;diff 集群名称&#xff09; kubectl config use-context kubernetes-adminkubernetesFind the pod that consumes the …...

网络简略总结

目录 一、三次握手 四次挥手 1、三次握手:为了建立长链接进行交互即建立一个会话,使用http/https协议 2、四次挥手是一个断开连接释放服务器资源的过程 3、如果已经建立了连接,但是客户端突然出现故障了怎么办? 4、谁可以中断连接?客户端还是服务端还是都可以? 5、…...

如何处理错误情况

处理错误情况是确保自动窗帘系统稳定运行的重要一环。在编写代码时&#xff0c;你需要考虑可能发生的各种错误情况&#xff0c;并编写相应的错误处理代码。下面是一些处理错误情况的常见方法&#xff1a; (1)错误检测&#xff1a; 首先&#xff0c;你需要能够检测到错误的发生。…...

【Greenhills】MULTI IDE-GHS最新版本Compiler 23.5.4的兼容性问题

【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 关于GHS推出的最新编译器版本 Compiler 2023.5.4在GHS以前版本的MULTI IDE上面能否使用的问题 2、 问题场景 针对于&#xff0c;客户使用MULTI IDE 8.1.4以前的IDE版本&#xff0c;想要搭载使用最新版本的编译器…...

用连续自然数之和来表达整数 - 华为OD统一考试(C卷)

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

SQLiteC/C++接口详细介绍之sqlite3类(十二)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十一&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十三&#xff09; ​37.sqlite3_load_extension 用于在SQLit…...

linux系统--------------mysql数据库管理

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

网络——入门基础

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

二、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语言的&#xff0c;不是windows操作系统的&#xff0c;和PATH环境变量完全不同classpath环境变量是给classloader&#xff08;类加载器&#xff09;指路的java A 。执行后&#xff0c;先启动JVM&#xff0c; JVM启动classload…...

Linux快速入门,上手开发 01.学习路线

少时曾许凌云志&#xff0c;当取世间第一流 再见少年拉满弓&#xff0c;不惧岁月不飓风 —— 24.3.20 1.Linux的发展历史 2.VM虚拟机的Linux初体验 3.图形化页面设置系统——快速上手 4.命令行操作——向专业前进 5.核心操作命令——必知必会&#xff08;管理企业级权限/定位b…...

JSX return里面如何用if判断

在JSX中,由于不能直接使用传统的JavaScript ​​if​​ 语句,但可以通过条件渲染来实现类似的效果。以下是一些方法: 1. 三元运算符(Ternary Operator) 最简单的条件渲染方式是使用三元运算符: return (<div>{condition ? <ComponentIfTrue /> : <Com…...

Vulnhub靶机渗透:DC-7打靶记录

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

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...