Python类的定义和使用详情
前言写一个能用的类不难写一个经得起扩展的类却需要理解不少语法细节class语句的完整形式、类文档串docstring的位置、构造函数的约束、继承与方法重写、以及双下划线开头的名字为什么会消失。常见误解有两个一是以为__name这种双下划线前缀的属性是私有成员外部绝对访问不到二是以为重写父类方法时不需要调用super()。前者是误解Python 只是做名字改写name mangling不是访问控制后者要看场景__init__的重写几乎一定要调super().__init__()否则父类的初始化逻辑会被跳过。本文按怎么定义、怎么用、怎么继承、怎么封装的顺序把类的语法细节讲全。一、class语句的完整形式class语句的基本形式是class 类名(基类列表):类体就是缩进块。类体第一条语句如果是一个字符串字面量会被当作该类的文档串。# 适用于 Python 3.8class Circle:表示一个圆。属性:radius: 半径必须为正数。pi 3.141592653589793 # 类属性def __init__(self, radius):if radius 0:raise ValueError(半径必须为正)self.radius radiusdef area(self):return Circle.pi * self.radius ** 2c Circle(2)print(c.area()) # 12.566370614359172print(Circle.__doc__.splitlines()[0]) # 表示一个圆。几个语法要点类名习惯用大驼峰CapWords函数用蛇形snake_case基类列表可以为空此时隐式继承object类体里可以写任意语句赋值、条件、循环、嵌套函数它们在定义时执行类体的文档串必须紧跟在class行之后否则不会被识别为__doc__。二、__init__与实例化__init__不是构造函数它只负责初始化已经被创建出来的实例真正的创建由__new__完成。__init__必须返回None返回别的值会抛TypeError。# 适用于 Python 3.8class User:def __init__(self, name, rolesNone):self.name name# 不要用可变对象当默认参数self.roles list(roles) if roles is not None else []def add_role(self, role):if role not in self.roles:self.roles.append(role)def __repr__(self):return fUser({self.name!r}, roles{self.roles!r})u User(Ada)u.add_role(admin)print(u) # User(Ada, roles[admin])print(User(Bob).roles) # []这里刻意避开了def __init__(self, roles[])这个经典陷阱默认参数在函数定义时求值一次可变默认参数会被所有调用共享。三、继承、重写与super()子类用class Sub(Base):声明。重写方法时如果希望保留父类行为用super()调用父类实现。super()走的是方法解析顺序MRO不是简单的父类。# 适用于 Python 3.8class Animal:def __init__(self, name):self.name namedef speak(self):return ...class Dog(Animal):def __init__(self, name, breed):super().__init__(name) # 别忘了这一行self.breed breeddef speak(self):return f{self.name} 说汪汪d Dog(Rex, 柴犬)print(d.speak()) # Rex 说汪汪print(isinstance(d, Animal)) # Trueprint(Dog.__mro__) # (Dog, Animal, object)如果子类__init__忘了super().__init__(name)self.name就不会被设置之后调用speak()会直接AttributeError。关系判断方式结果子类实例是父类实例吗isinstance(d, Animal)True子类是父类的子类吗issubclass(Dog, Animal)True子类继承父类私有名吗名字改写后仍可访问但名字被改写子类能覆盖类属性吗在子类里重新赋值即可可以四、名字改写不是私有以双下划线开头、且最多一个下划线结尾的名字例如__secret会被改写成_类名__secret。这叫做名字改写name mangling目的是避免子类意外覆盖它不是访问控制。# 适用于 Python 3.8class Vault:def __init__(self):self.__secret 42self._single ok # 单下划线只是约定内部使用self.__dunder__ 特殊方法名不改写def reveal(self):return self.__secretv Vault()print(v.reveal()) # 42print(v._Vault__secret) # 42改写后照样能访问print(vars(v))# {_Vault__secret: 42, _single: ok, __dunder__: 特殊方法名不改写}结论双下划线前缀只能防止子类不小心重名阻止不了任何人访问。真正的封装靠的是清晰的接口约定而不是名字前缀。五、用抽象基类定义接口如果一个类只用来规定子类必须实现哪些方法可以用abc模块的ABC和abstractmethod。含未实现抽象方法的类不能被实例化。# 适用于 Python 3.8from abc import ABC, abstractmethodclass Shape(ABC):abstractmethoddef area(self):子类必须实现。def describe(self):return f面积是 {self.area()}class Square(Shape):def __init__(self, side):self.side sidedef area(self):return self.side ** 2print(Square(3).describe()) # 面积是 9try:Shape() # TypeError: Cant instantiate abstract classexcept TypeError as e:print(TypeError:, e)六、综合示例# 适用于 Python 3.8class Stack:一个简单的后进先出栈。def __init__(self, itemsNone):self._items list(items) if items is not None else []def push(self, item):self._items.append(item)def pop(self):if not self._items:raise IndexError(pop from empty stack)return self._items.pop()def __len__(self):return len(self._items)def __repr__(self):return fStack({self._items!r})s Stack([1, 2])s.push(3)print(len(s)) # 3print(s.pop()) # 3print(s) # Stack([1, 2])常见坑点可变默认参数❌python # 适用于 Python 3.8 class A: def __init__(self, items[]): self.items items✅python # 适用于 Python 3.8 class A: def __init__(self, itemsNone): self.items [] if items is None else list(items)子类__init__不调super().__init__()❌python # 适用于 Python 3.8 class Dog(Animal): def __init__(self, name, breed): self.breed breed # 缺 name✅python # 适用于 Python 3.8 class Dog(Animal): def __init__(self, name, breed): super().__init__(name) self.breed breed文档串位置放错❌python # 适用于 Python 3.8 class A: pi 3.14 这是圆的说明 # 不是文档串✅python # 适用于 Python 3.8 class A: 这是圆的说明 pi 3.14以为双下划线是真私有❌python # 适用于 Python 3.8 class A: def __init__(self): self.__v 1 # 以为外部 a.__v 一定失败就一定安全✅python # 适用于 Python 3.8 # 用单下划线表达内部使用并提供公开方法访问 class A: def __init__(self): self._v 1def get_v(self): return self._v 重写方法时签名不一致❌python # 适用于 Python 3.8 class Base: def save(self, path, overwriteFalse): ...class Sub(Base): def save(self, path): # 少了一个参数替换使用时会崩 ... ✅python # 适用于 Python 3.8 class Sub(Base): def save(self, path, overwriteFalse): ...抽象基类忘了实现抽象方法就想实例化❌python # 适用于 Python 3.8 class Square(Shape): passSquare() # TypeError ✅python # 适用于 Python 3.8 class Square(Shape): def area(self): return 1类属性与实例属性同名造成困惑❌python # 适用于 Python 3.8 class A: count 0def bump(self): self.count 1 # 生成实例属性类属性不变 ✅python # 适用于 Python 3.8 class A: count 0def bump(self): type(self).count 1 总结语法点要点class语句类体在定义时执行一次文档串必须是类体第一条语句__init__只初始化必须返回None继承super().__init__()不要漏名字改写__x变_类名__x非私有ABC未实现抽象方法不能实例化定义类时最容易出错的不是语法而是几个约定可变默认参数、super().__init__()、以及把双下划线当私有。把接口用文档串和公开方法表达清楚比堆名字前缀更可靠。

相关新闻

Python线程编程之Thread详解

Python线程编程之Thread详解

前言 threading.Thread 是多线程编程的入口类,但很多人只用了它的 start() 和 join(),对构造函数里那几个参数、run() 与 start() 的分工、ident 与 native_id 的区别、异常到底去了哪里,都是模糊的。结果是遇到「线程静默退出」「异常看不见…

2026/10/10 19:25:02 阅读更多 →
论文降重工具怎么选?五款实测对比与查重原理全解析

论文降重工具怎么选?五款实测对比与查重原理全解析

1. 先搞清楚查重系统怎么工作,再谈降重工具怎么选1.1 标红规则:连续多少字符一样会被判重论文降重大概是硕博阶段最容易被低估的一件苦差事。头一回把初稿提交到学校指定的查重平台,看到接近30%的重复率,很多人整个周末都在重写。…

2026/10/10 19:25:02 阅读更多 →
6大Lens质量评测集全解析:jacobian-lens如何科学量化“透镜“的好坏

6大Lens质量评测集全解析:jacobian-lens如何科学量化“透镜“的好坏

【免费下载链接】jacobian-lens Companion code for the global workspace interpretability paper 项目地址: https://gitcode.com/gh_mirrors/ja/jacobian-lens 点击查看 免费下载 你是否好奇语言模型内部到底在"想什么"?jacobian-lens&…

2026/10/10 19:25:02 阅读更多 →

最新新闻

Spring创建Bean失败排查:BeanCreationException根因分析与解决实践

Spring创建Bean失败排查:BeanCreationException根因分析与解决实践

"Error creating bean with name xxx..." 这一行红字,几乎是每个用Spring写后端的人都会在启动控制台里撞见的画面。我这些年帮同事排查、也自己在项目里踩,见过太多人一看到这句话就CtrlF搜Bean名字,然后从类头翻到类尾&#xff0…

2026/10/10 22:36:21 阅读更多 →
二叉树最大深度详解:从递归到迭代,彻底理解树的深度计算

二叉树最大深度详解:从递归到迭代,彻底理解树的深度计算

二叉树的最大深度,这题在力扣hot100题里基本是每个刷题人的必经之路,也是二叉树系列里最入门的一道。但我发现一个很有意思的现象:题目本身逻辑极其简单,可评论区里"递归栈溢出""运行时错误""空指针&quo…

2026/10/10 22:36:21 阅读更多 →
Cesium 1.19.11离线加载自定义影像与哈密地形完整实践

Cesium 1.19.11离线加载自定义影像与哈密地形完整实践

前阵子接了一个三维地理信息展示的活儿,要求在内网环境里用 Cesium 搭建一个以哈密区域为核心的三维场景。客户端那边一口咬定必须用 1.19.11 这个老版本,说是之前的系统全部基于这个版本扩展的,升级换新引擎会让一堆历史功能和控件全部报废。…

2026/10/10 22:36:21 阅读更多 →
机场智能化系统建设提案:从总体架构到PPT汇报的完整方法论

机场智能化系统建设提案:从总体架构到PPT汇报的完整方法论

简介:这是一份面向机场智能化规划人员、系统集成工程师及民航相关专业师生的专业课件,完整呈现机场智能化系统建设提案的PPT教案。资源包含1个pptx演示文件,大小约3.34MB,便于直接用于项目汇报、教学演示或方案宣讲。内容以AODB机…

2026/10/10 22:36:21 阅读更多 →
向量数据库与普通数据库选型实战指南

向量数据库与普通数据库选型实战指南

1. 项目概述:为什么“向量数据库 vs 普通数据库”突然成了高频选型题最近在多个技术交流群、内部架构评审会和一线开发者的日常提问里,反复看到一句话:“这个需求到底该用向量数据库,还是直接在MySQL/PostgreSQL里加个pgvector插件…

2026/10/10 22:36:21 阅读更多 →
自动分类不是玄学:Paperless-ngx 的机器学习文档归类机制全揭秘

自动分类不是玄学:Paperless-ngx 的机器学习文档归类机制全揭秘

自动分类不是玄学:Paperless-ngx 的机器学习文档归类机制全揭秘 【免费下载链接】paperless-ngx A community-supported supercharged document management system: scan, index and archive all your documents 项目地址: https://gitcode.com/GitHub_Trending/p…

2026/10/10 22:35:20 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →