Python 类五大方法 完整版学习笔记

本笔记结合工程化开发、PyQt5 GUI 开发、工具类 / SDK 封装实战场景,梳理 Python 类中 5 种核心方法的定义、语法、适用场景、避坑要点,可直接复制保存为永久笔记。

一、五大方法极简速览总表

|------|----------------|-------|---------------|-------------------------------|
| 方法类型 | 标识 / 装饰器 | 核心参数 | 调用主体 | 核心用途 |
| 实例方法 | 无装饰器 | self | 仅实例对象 | 操作单个实例的独有数据、业务逻辑 |
| 静态方法 | @staticmethod | 无默认参数 | 类本身 / 实例对象 | 纯工具函数,与类 / 实例无数据绑定 |
| 类方法 | @classmethod | cls | 类本身 / 实例对象 | 操作类全局属性、统一类规则、工厂模式创建对象,避免硬写类名 |
| 属性方法 | @property 系列 | self | 仅实例对象 | 把方法伪装成属性,做数据校验、读写控制 |
| 魔术方法 | xxx 双下划线格式 | 自定义 | 系统自动触发 / 手动调用 | 控制类的底层行为、生命周期、内置规则 |

二、分方法详细精讲(含代码示例 + 实战场景 + 避坑指南)

1. 实例方法(日常开发最高频)

核心定义

Python 类中默认的方法类型,绑定单个实例对象,是面向对象开发最基础、最常用的方法。核心作用是操作实例自身的独有属性、实现单个对象的业务逻辑。

核心语法规则
  1. 无任何装饰器,第一个参数必须是 self(行业约定写法,非关键字,可自定义但不推荐)
  2. self 代表「当前创建的实例对象本身」
  3. 只能通过先创建实例对象,再通过对象调用,无法直接通过类名调用
  4. 可访问:实例属性 + 类属性
标准代码示例
python 复制代码
# 基础示例

class Person:

    # 实例属性初始化(魔术方法__init__本身也是特殊的实例方法)

    def __init__(self, name, age):

        self.name = name  # 实例独有属性

        self.age = age

    # 实例方法

    def show_info(self):

        # 通过self访问实例属性

        print(f"姓名:{self.name},年龄:{self.age}")

    def update_age(self, new_age):

        if 0 < new_age 50:

            self.age = new_age

# 调用方式:必须先实例化

p = Person("张三", 25)

p.show_info()

p.update_age(26)
PyQt5 实战适配示例

PyQt5 中 95% 的窗口、控件方法,都必须用实例方法实现:

python 复制代码
from PyQt5.QtWidgets import QMainWindow, QPushButton

class MainWindow(QMainWindow):

    def __init__(self):

        super().__init__()

        self.btn = QPushButton("点击", self)  # 实例控件属性

        self.init_ui()  # 实例方法调用

    # 实例方法:初始化UI

    def init_ui(self):

        self.btn.clicked.connect(self.on_btn_click)

    # 实例方法:按钮点击事件

    def on_btn_click(self):

        print(f"按钮被点击,窗口对象:{self}")
适用场景
  1. 操作单个对象的独有数据、状态(如窗口控件、用户实例、业务对象)
  2. 实现与实例生命周期绑定的业务逻辑
  3. PyQt5 窗口 / 控件的 UI 初始化、事件响应、数据交互
避坑指南
  1. 禁止直接通过类名调用实例方法(会报错缺少 self 参数)
  2. 实例方法内,必须通过 self.xxx 访问实例属性,禁止直接写变量名
  3. 仅单个实例使用的临时参数,不要硬塞到__init__里,避免实例属性臃肿

2. 静态方法(@staticmethod)

核心定义

类中的纯独立工具函数,与类本身、实例对象均无强制绑定,既不接收 self、也不接收 cls,只是逻辑上归属于类的命名空间。你可以把它理解为 "借类的命名空间存放的普通函数",和类的关联仅停留在 "逻辑归类"。

核心语法规则
  1. 必须加装饰器 @staticmethod
  2. 无默认强制参数,和普通函数写法完全一致
  3. 调用方式:类名。方法 ()、实例对象。方法 () 均合法
  4. 无法直接访问:类属性、实例属性,如需访问类属性只能硬写类名(这是其核心局限)
标准代码示例
python 复制代码
class DataTool:

    # 静态方法:纯工具函数,和类/实例无数据绑定

    @staticmethod

    def add(a, b):

        return a + b

    @staticmethod

    def is_valid_phone(phone: str):

        """校验手机号格式,纯工具逻辑"""

        return len(phone) == 11 and phone.isdigit()

# 调用方式

# 1. 类直接调用

print(DataTool.add(3, 5))

print(DataTool.is_valid_phone("13800138000"))

# 2. 实例调用

tool = DataTool()

print(tool.add(10, 20))
关键局限(结合你的观察)

静态方法最大的问题是:如果需要访问类属性,必须硬写类名(如Config.app_name)。这会导致两个严重问题:

  1. 当类名修改时,所有硬写类名的地方都要同步修改,维护成本高;
  2. 子类继承时,静态方法依然指向父类的类名,无法自动适配子类,继承体系失效(后续类方法会解决这个问题)。
适用场景
  1. 与类相关、但不操作类 / 实例任何属性的纯工具逻辑
  2. 通用校验、格式转换、简单计算等无状态的辅助函数
  3. 把零散的工具函数收拢到类的命名空间下,避免全局函数污染
避坑指南
  1. 禁止在静态方法中硬写类名访问类属性,会导致类名修改、子类继承时代码失效,这种场景请改用类方法(你的核心观察点)
  2. 不要在静态方法中操作实例数据,职责完全错位
  3. 完全和类无关的工具函数,不要强行塞进类里,直接写独立函数更优雅

3. 类方法(@classmethod)

核心定义

绑定类本身 的方法,而非单个实例。你对它的定位非常精准 ------ 它本质是 "为解决静态方法硬写类名问题而设计的特殊静态方法",核心作用是通过cls参数自动绑定当前类,实现类属性的灵活操作、类级别的统一规则,同时完美支持继承。

核心语法规则
  1. 必须加装饰器 @classmethod
  2. 第一个参数必须是 cls(行业约定写法,代表当前调用的类本身,而非实例)
  3. 调用方式:类名。方法 () 优先,实例对象。方法 () 语法也合法
  4. 可访问:类属性、其他类方法,无法直接访问实例属性 / 实例方法
  5. 核心优势:cls会自动适配调用者(调用父类时是父类,调用子类时是子类),彻底避免硬写类名的问题
标准代码示例(突出与静态方法的差异)
python 复制代码
class Config:

    # 类全局属性:所有实例共享

    app_name = "LhPyQt5"

    theme = "dark"

    version = "1.0.2"

    # 类方法:修改全局配置(对比静态方法:无需硬写Config)

    @classmethod

    def set_config(cls, name, value):

        # cls 等价于当前调用的类(Config/子类),自动适配

        if not hasattr(cls, name):

            raise AttributeError(f"配置项【{name}】不存在")

        setattr(cls, name, value)

    # 类方法:工厂模式,快速创建对象

    @classmethod

    def create_light_config(cls):

        cls.theme = "light"

        return cls()

# 1. 基础调用:无需硬写类名,修改类属性更灵活

Config.set_config("version", "1.0.3")

print(Config.version)

# 2. 继承场景:cls自动适配子类(静态方法做不到这一点)

class DevConfig(Config):

    app_name = "开发环境配置"

# 调用子类的类方法,cls自动指向DevConfig

dev_config = DevConfig.create_light_config()

print(dev_config.app_name)  # 输出:开发环境配置(静态方法会输出父类的LhPyQt5)
与静态方法的核心差异(呼应你的观察)

|---------|------------------------|----------------------|
| 对比维度 | 类方法 (@classmethod) | 静态方法 (@staticmethod) |
| 类属性访问方式 | 通过 cls 自动绑定,无需硬写类名 | 必须硬写类名,否则无法访问 |
| 继承适配性 | cls 自动指向子类,完美支持继承 | 硬写父类名,子类继承时失效 |
| 设计意图 | 操作类本身的属性 / 逻辑,是类的 "成员" | 纯工具逻辑,只是借类的命名空间存放 |

适用场景
  1. 全局配置类、全局状态管理、类属性统一读写(需要灵活访问类属性)
  2. 工厂模式:统一封装对象的创建逻辑,简化实例化(支持子类定制创建规则)
  3. 批量修改类的全局规则,无需创建实例
  4. 避免在静态方法中硬写类名,提升代码可维护性、可继承性(你的核心需求场景)
避坑指南
  1. 禁止在类方法中访问 self 实例属性,类方法执行时实例可能还未创建
  2. 实例调用类方法时,cls 依然指向类本身,不会变成实例(如 obj.set_config () 中 cls 还是 Config)
  3. 不要用类方法操作单个实例的独有数据,职责边界混乱(实例数据交给实例方法)

4. 属性方法(@property 系列)

核心定义

类的方法伪装成普通属性,调用时无需加 (),核心作用是实现属性的读写拦截、数据校验、权限控制、只读限制,是数据封装的核心语法。

核心语法规则
  1. 核心装饰器 @property,配套 @xxx.setter(修改)、@xxx.deleter(删除)
  2. 基础读取方法必须带 self 参数,绑定实例对象
  3. 调用方式:实例。属性名,无需加括号,和普通属性用法完全一致
  4. 内部真实数据约定用单下划线 _xxx开头,标记为内部私有变量
完整三形态代码示例
python 复制代码
class Student:

    def __init__(self, score):

        self._score = score  # 内部私有变量,约定不对外直接访问

    # 1. 读取属性:@property,只读

    @property

    def score(self):

        """读取分数,对外暴露的属性"""

        return self._score

    # 2. 修改属性:@score.setter,赋值拦截+校验

    @score.setter

    def score(self, value):

        """修改分数,强制校验数值合法性"""

        if not isinstance(value, int):

            raise ValueError("分数必须是整数")

        if not 0 

            raise ValueError("分数必须在0-100之间")

        self._score = value

    # 3. 删除属性:@score.deleter,删除拦截

    @score.deleter

    def score(self):

        print("⚠️ 分数属性已被删除")

        del self._score

# 使用示例

s = Student(80)

# 读取:不用加(),和普通属性一模一样

print(s.score)

# 赋值:直接等于号,自动触发setter校验

s.score = 95

print(s.score)

# 非法赋值,自动拦截报错

# s.score = 200

# 删除:触发deleter

del s.score
适用场景
  1. 类属性需要做读写校验、格式转换、权限控制
  2. 把复杂的计算逻辑伪装成简单属性,简化外部调用
  3. 实现只读属性,禁止外部随意修改
  4. PyQt5 窗口控件属性封装、配置类参数校验、数据模型字段管控
避坑指南
  1. 内部存储变量必须和 @property 方法名不同,否则会触发无限递归报错
  2. 只有 @property 无 setter 时,属性为只读,外部赋值会直接报错
  3. 单下划线_xxx 只是行业约定,语法上依然能外部访问,仅做提示作用
  4. 不要在 @property 方法中写耗时、有副作用的逻辑,调用者会误以为是普通属性读取

5. 魔术方法(双下划线__xxx__方法)

核心定义

Python 内置的、以双下划线开头和结尾的特殊方法,无需手动调用,系统会在特定场景自动触发,用来控制类的底层行为、生命周期、内置操作规则,是 Python 面向对象的底层核心。

核心语法规则
  1. 固定格式:方法名,双下划线包裹
  2. 无需手动调用,触发时机由 Python 解释器定义
  3. 可重写自定义逻辑,覆盖系统默认行为
  4. 无需装饰器,本质是特殊的实例方法 / 类方法
高频常用魔术方法示例
python 复制代码
class Demo:

    # 1. 实例初始化:创建实例时自动触发,最常用

    def __init__(self, name):

        self.name = name

        print("实例被创建,__init__执行")

    # 2. 打印对象时自动触发,自定义对象的字符串展示

    def __str__(self):

        return f"Demo对象:{self.name}"

    # 3. 对象被销毁时自动触发,资源释放

    def __del__(self):

        print(f"对象【{self.name}】被销毁,__del__执行")

    # 4. 给属性赋值时自动触发,拦截所有属性赋值

    def __setattr__(self, key, value):

        print(f"正在设置属性:{key} = {value}")

        # 必须调用父类方法完成真实赋值,否则属性无法保存

        super().__setattr__(key, value)

    # 5. 调用len()函数时自动触发,自定义长度计算

    def __len__(self):

        return len(self.name)

# 触发演示

# 触发__init__

d = Demo("测试")

# 触发__str__

print(d)

# 触发__setattr__

d.age = 20

# 触发__len__

print(len(d))

# 程序结束时触发__del__
适用场景
  1. init:实例属性初始化,所有类的基础用法
  2. str:自定义对象打印格式,调试日志必备
  3. setattr /getattr:属性读写拦截,动态属性管控
  4. del:资源释放、关闭文件 / 数据库连接 / 网络请求
  5. 自定义容器类、运算符重载、上下文管理器等高级场景
避坑指南
  1. __init__是实例初始化方法,不是创建实例的方法,实例创建由__new__完成
  2. 重写魔术方法时,必须保证父类的原有逻辑被正确调用(如 super ().setattr),否则会导致底层功能失效
  3. 不要滥用魔术方法,绝大多数业务场景只需掌握__init__、__str__即可,过度使用会导致代码可读性极差
  4. __del__触发时机由 Python 垃圾回收机制决定,不要依赖它做关键资源释放,优先用 with 上下文管理器

三、终极记忆口诀(优化后突出核心差异)

  1. self 管对象,static 纯工具(需硬写类名),cls 管类(自动适配无硬写)
  2. property 伪装属性,做校验、控读写
  3. 双下划线魔术方法,系统自动跑,管底层
  4. PyQt 开发 95% 场景用实例方法,全局配置用类方法(避硬写),纯工具用静态方法
相关推荐
a7963lin1 小时前
html标签怎样表示搜索框_input type=search语义优化【操作】
jvm·数据库·python
XiYang-DING1 小时前
【Java EE】定时器
java·python·java-ee
小德乐乐1 小时前
AlphaFold3 预测蛋白结构 分子互作分析出图 代理计算 本地部署 可指导
图像处理·python
a7963lin1 小时前
Python数据分析如何识别异常值_IQR四分位距检测法实战
jvm·数据库·python
Fuly10241 小时前
java面试知识点复习
java·开发语言·面试
m0_613856291 小时前
如何解决宝塔面板Web端文件管理器打开目录时反应极其缓慢
jvm·数据库·python
wltx16881 小时前
独立站搭建需要做氨氮检测仪展示吗?
人工智能·python
The_superstar61 小时前
衡山派D133EBS入门笔记
笔记·python·c·衡山派·小曹越
Air_July1 小时前
Brower User Web UI部署详细步骤
人工智能·python·测试工具