跳到主要内容
Python 面向对象编程(OOP)核心概念与实战 | 极客日志
Python 算法
Python 面向对象编程(OOP)核心概念与实战 Python 面向对象编程(OOP)将数据和操作封装为对象,适合开发复杂项目。类与对象定义、属性分类、三种方法类型,深入剖析封装、继承、多态三大特性,并介绍魔术方法与模块化编程。通过实战示例展示私有属性保护、super 调用及自定义运算,帮助读者掌握 OOP 核心思维与工程实践。
片刻 发布于 2026/2/9 更新于 2026/5/30 22 浏览Python 面向对象编程(OOP)全解析
Python 是一门纯面向对象的语言,一切皆对象(数字、字符串、列表等本质都是对象)。本文将从零基础视角,系统讲解 Python 面向对象编程的核心概念:类与对象、封装 / 继承 / 多态三大特性,以及魔术方法、模块与包的实用知识,帮你彻底掌握 OOP 编程思维。
一、OOP 核心基础:类与对象
面向对象的核心是类 和对象 ,类是对象的'模板',对象是类的'实例'——就像'汽车'是一个类,而你家的特斯拉、楼下的宝马,都是这个类的具体对象。
1.1 类的定义
类是对一组具有相同属性 (特征)和方法 (行为)的对象的抽象描述,通过 class 关键字定义,语法如下:
class 类名 (父类 ):
"""类的文档字符串:说明类的功能"""
类属性 = 初始值
def __init__ (self, 参数 1 , 参数 2 , ... ):
self .实例属性 1 = 参数 1
self .实例属性 2 = 参数 2
def 方法名 (self , 参数):
方法体
命名规范 :类名采用大驼峰命名法 (每个单词首字母大写,无下划线),如 Person、Student、Car;属性和方法采用小写字母 + 下划线的命名法,如 user_name、get_info。
1.2 对象的创建与使用
对象是类的具体实例,通过类名 () 创建,创建过程也叫实例化 ;创建后可通过 对象。属性 访问属性,通过 对象。方法 () 调用方法。
实战示例:定义 Person 类并实例化
class Person :
"""人类:包含姓名、年龄属性,以及说话、跑步方法"""
species = "人类"
( ):
.name = name
.age = age
( ):
( )
( ):
( )
p1 = Person( , )
p2 = Person( , )
(p1.name)
(p2.age)
(p1.species)
(Person.species)
p1.speak( )
p2.run()
def
__init__
self, name, age
self
self
def
speak
self, content
"""说话方法"""
print
f"{self.name} 说:{content} "
def
run
self
"""跑步方法"""
print
f"{self.name} 今年{self.age} 岁,正在跑步!"
"张三"
25
"李四"
30
print
print
print
print
"Python 面向对象编程真有趣!"
1.3 类属性与实例属性的区别 类属性和实例属性是 OOP 的基础概念,核心区别在于作用范围 和归属 ,具体对比如下:
类型 定义位置 归属 作用范围 访问方式 类属性 类内部、方法外 类本身 所有实例共享 类。属性 / 对象。属性 实例属性 init 方法内具体实例 仅当前实例独有 仅对象。属性
注意 :若通过 对象。类属性 = 新值 赋值,不会修改类本身的类属性,而是为该对象创建一个同名的实例属性 ,后续该对象访问此属性时,优先读取自己的实例属性。
p1.species = "智人"
print (p1.species)
print (p2.species)
print (Person.species)
1.4 实例方法、类方法、静态方法 类中的方法分为三种,分别适用于不同场景,核心区别在于参数要求 和调用方式 ,均通过 def 定义,配合装饰器区分:
1.4.1 实例方法
最常用的方法类型,无装饰器;
第一个参数必须是 self,代表实例本身 ;
可访问 / 修改实例属性和类属性;
仅能通过对象 调用,不能通过类直接调用。
1.4.2 类方法
用 @classmethod 装饰器修饰;
第一个参数必须是 cls,代表类本身 ;
可访问 / 修改类属性,不能直接访问实例属性 (无 self);
可通过类 或对象 调用,推荐用类调用。
1.4.3 静态方法
用 @staticmethod 装饰器修饰;
无默认参数(无需 self/cls),与普通函数类似;
不能访问类属性和实例属性,仅做独立的功能实现;
可通过类 或对象 调用,推荐用类调用。
实战示例:三种方法的使用 class Student :
"""学生类:演示三种方法"""
school = "北京大学"
def __init__ (self, name, score ):
self .name = name
self .score = score
def get_score (self ):
return f"{self.name} 的成绩是:{self.score} "
@classmethod
def change_school (cls, new_school ):
cls.school = new_school
print (f"学校已修改为:{cls.school} " )
@staticmethod
def is_pass (score ):
if score >= 60 :
return "及格"
else :
return "不及格"
s = Student("王五" , 88 )
print (s.get_score())
Student.change_school("清华大学" )
print (Student.school)
print (Student.is_pass(59 ))
print (s.is_pass(s.score))
二、OOP 三大核心特性:封装、继承、多态 封装、继承、多态是面向对象编程的三大支柱 ,也是 OOP 思想的核心体现,通过这三个特性,能实现代码的高复用、高扩展、低耦合。
2.1 封装:隐藏细节,对外提供接口 封装 的核心思想是:将类的属性和方法隐藏 起来,不允许外部直接访问或修改,而是通过类提供的公共方法 实现对属性的操作,从而保证数据的安全性和一致性。
简单来说,就是'把内部细节藏起来,只留门让外部访问'——比如手机的内部电路是封装的,外部仅通过屏幕、按键等接口操作。
Python 中的封装实现 Python 没有专门的关键字(如 Java 的 private、public)实现封装,而是通过命名规范 和属性装饰器 实现:
下划线命名规范 :约定俗成的封装,无强制限制
_属性/方法:单下划线,代表受保护的 ,建议外部不要直接访问,仅允许类和子类访问;
__属性/方法:双下划线,代表私有的 ,Python 会对其进行名称改写 ,外部无法直接访问,仅允许类内部访问。
property 装饰器 :将方法伪装成属性,实现对私有属性的安全访问和修改。
实战示例 1:双下划线实现私有属性 / 方法 class Phone :
"""手机类:演示封装"""
def __init__ (self, brand, price ):
self .brand = brand
self .__price = price
def get_price (self ):
return f"手机价格:{self.__price} 元"
def set_price (self, new_price ):
if isinstance (new_price, int ) and new_price > 0 :
self .__price = new_price
print ("价格修改成功" )
else :
print ("价格格式错误,必须是正整数" )
def __call_phone (self ):
print ("正在拨打电话..." )
def call (self ):
self .__call_phone()
p = Phone("华为" , 5999 )
print (p.brand)
print (p._Phone__price)
print (p.get_price())
p.set_price(6999 )
p.set_price(-100 )
p.call()
实战示例 2:property 装饰器实现属性的安全访问 property 装饰器可以将获取属性的方法 伪装成属性 ,配合 @属性名.setter 装饰器,将修改属性的方法 也伪装成属性,使用时无需加括号,更简洁。
class Person :
def __init__ (self, name, age ):
self .name = name
self .__age = age
@property
def age (self ):
return self .__age
@age.setter
def age (self, new_age ):
if isinstance (new_age, int ) and 0 < new_age < 150 :
self .__age = new_age
else :
raise ValueError("年龄必须是 0-150 之间的正整数" )
p = Person("赵六" , 28 )
print (p.age)
p.age = 30
print (p.age)
2.2 继承:代码复用,实现类的扩展 继承 的核心思想是:让一个子类(派生类) 继承另一个父类(基类 / 超类) 的属性和方法,子类可直接使用父类的功能,也可根据需求重写 父类方法或添加 新的属性 / 方法,从而实现代码的最大化复用。
简单来说,就是'子类站在父类的肩膀上,不用重复造轮子'——比如'学生'和'老师'都是'人'的子类,可继承'人'的姓名、年龄属性和说话方法,再各自添加专属的属性(如学生的成绩、老师的工号)和方法。
2.2.1 继承的基本语法
class 子类名 (父类名 ):
def __init__ (self, 父类参数,子类参数 ):
super ().__init__(父类参数)
self .子类参数 = 子类参数
def 子类方法 (self ):
方法体
def 父类方法 (self ):
重写后的方法体
class 子类名 (父类 1 , 父类 2 , ...):
类体
关键 :子类的构造方法中,需通过 super().__init__() 调用父类的构造方法,否则父类的实例属性无法被初始化。
2.2.2 单继承实战示例
class Person :
def __init__ (self, name, age ):
self .name = name
self .age = age
def speak (self ):
print (f"{self.name} 今年{self.age} 岁" )
class Student (Person ):
def __init__ (self, name, age, score ):
super ().__init__(name, age)
self .score = score
def show_score (self ):
print (f"{self.name} 的成绩是:{self.score} " )
def speak (self ):
print (f"{self.name} 今年{self.age} 岁,成绩为{self.score} " )
class Teacher (Person ):
def __init__ (self, name, age, job_num ):
super ().__init__(name, age)
self .job_num = job_num
def show_job_num (self ):
print (f"{self.name} 的工号是:{self.job_num} " )
s = Student("小明" , 18 , 95 )
t = Teacher("李老师" , 35 , "T001" )
print (s.name)
t.speak()
s.show_score()
t.show_job_num()
s.speak()
2.2.3 方法重写与 super () 的进阶使用
方法重写 :子类方法名与父类完全一致时,子类方法会覆盖 父类方法,调用时优先执行子类方法;若需在子类中调用父类被重写的方法,可通过 super().父类方法 () 实现。
super() :不仅能调用父类的构造方法,还能调用父类的任意方法,是子类与父类交互的重要桥梁。
class Person :
def eat (self ):
print ("人在吃饭" )
class Student (Person ):
def eat (self ):
super ().eat()
print ("学生吃完饭要写作业" )
s = Student()
s.eat()
2.2.4 多继承(了解) Python 支持子类同时继承多个父类,语法为 class 子类 (父类 1, 父类 2),但多继承会带来菱形问题 (多个父类继承自同一个基类,子类调用方法时可能出现歧义),实际开发中慎用 ,优先使用单继承 + 组合的方式。
2.3 多态:一个接口,多种实现 多态 的核心思想是:同一个方法,作用在不同的对象上,会产生不同的执行结果 —— 即'一个接口,多种实现',多态的实现依赖于继承 和方法重写 。
多态能让代码更灵活、更易扩展,调用方法时无需关注对象的具体类型,只需保证对象实现了对应的方法即可。
实战示例:多态的实现
class Animal :
def __init__ (self, name ):
self .name = name
def cry (self ):
pass
class Dog (Animal ):
def cry (self ):
print (f"{self.name} :汪汪汪!" )
class Cat (Animal ):
def cry (self ):
print (f"{self.name} :喵喵喵!" )
class Duck (Animal ):
def cry (self ):
print (f"{self.name} :嘎嘎嘎!" )
def animal_cry (animal ):
animal.cry()
dog = Dog("大黄" )
cat = Cat("小白" )
duck = Duck("唐老鸭" )
animal_cry(dog)
animal_cry(cat)
animal_cry(duck)
上述示例中,animal_cry 函数是一个统一的接口 ,无需关注传入的是 Dog、Cat 还是 Duck 对象,只要对象实现了 cry 方法,就能正常执行,这就是多态的魅力。
三、Python 面向对象进阶:魔术方法 在 Python 中,以双下划线开头和结尾 的方法被称为魔术方法 (也叫特殊方法),如 __init__、__str__、__add__ 等。魔术方法无需手动调用,会在特定场景下自动触发 ,是实现 Python 对象特性的核心。
魔术方法丰富了类的功能,能让我们自定义对象的行为,比如自定义对象的打印格式、实现对象的加法运算等。以下介绍开发中最常用的魔术方法。
3.1 初始化与打印相关魔术方法
init :构造方法,创建实例时自动触发,初始化实例属性(最常用);
str :打印对象时自动触发,返回对象的字符串描述,默认返回 <__main__.类名 object at 内存地址>,可重写自定义格式;
repr :与 __str__ 类似,在终端直接输入对象名回车时触发,若未重写 __str__,则 print() 会调用 __repr__。
class Person :
def __init__ (self, name, age ):
self .name = name
self .age = age
def __str__ (self ):
return f"Person(name={self.name} , age={self.age} )"
p = Person("张三" , 25 )
print (p)
3.2 算术运算相关魔术方法 用于自定义对象的算术运算,如 __add__(+)、__sub__(-)、__mul__(*)等,让对象可以像数字一样进行运算。
class Point :
"""点类:实现两个点的坐标相加"""
def __init__ (self, x, y ):
self .x = x
self .y = y
def __add__ (self, other ):
new_x = self .x + other.x
new_y = self .y + other.y
return Point(new_x, new_y)
def __str__ (self ):
return f"Point({self.x} , {self.y} )"
p1 = Point(1 , 2 )
p2 = Point(3 , 4 )
p3 = p1 + p2
print (p3)
3.3 容器相关魔术方法 若想让自定义类的对象像列表、字典一样支持索引访问 (obj[index])、获取长度 (len(obj)),可重写容器相关魔术方法:
getitem :索引访问时触发,如 obj[index];
len :调用 len(obj) 时触发,返回对象的长度。
class MyList :
"""自定义列表类:模拟列表的索引和长度功能"""
def __init__ (self, data ):
self .data = data
def __getitem__ (self, index ):
return self .data[index]
def __len__ (self ):
return len (self .data)
ml = MyList([1 , 2 , 3 , 4 , 5 ])
print (ml[2 ])
print (len (ml))
四、Python 模块化编程:模块与包 当代码量越来越大时,将所有代码写在一个文件中会导致代码难以维护、复用性差;而模块化编程 是将代码按功能拆分为多个文件(模块),再通过包 组织多个模块,从而实现代码的高复用、高维护。
4.1 模块(Module) 模块 就是一个以 .py 为后缀的 Python 文件,文件中包含变量、函数、类等代码,其他文件可通过 import 语句导入模块,使用其中的内容。
内置模块 :Python 自带的模块,如 math、random、os,可直接导入使用;
第三方模块 :由开发者开发的模块,如 numpy、pandas,需先通过 pip install 安装,再导入;
自定义模块 :自己编写的 .py 文件,作为模块供其他文件调用。
4.1.1 模块的导入与使用
import 模块名
import 模块名 as 别名
from 模块名 import 函数名/类名/变量名
from 模块名 import 函数名 as 别名
from 模块名 import *
from 包名 import 模块名
from 包名。模块名 import 函数名
实战示例:自定义模块并导入
name = "Python 面向对象"
def add (a, b ):
return a + b
class Person :
def __init__ (self, name ):
self .name = name
def say (self ):
print (f"你好,{self.name} " )
创建主文件 main.py,导入并使用 mymodule:
import mymodule as mm
from mymodule import add, Person
print (mm.name)
print (add(3 , 5 ))
p = Person("张三" )
p.say()
4.2 包(Package) 包 是一个包含 __init__.py 文件的文件夹 ,用于组织多个相关的模块,解决模块命名冲突的问题。简单来说,包就是'模块的文件夹',而 __init__.py 是包的标识文件(即使为空也必须存在)。
包的结构示例 my_package/
__init__.py
module1.py
module2.py
main.py
包的导入与使用
import my_package.module1 as m1
import my_package.module2 as m2
from my_package import module1, module2
from my_package.module1 import 函数名/类名
init .py 的作用__init__.py 文件不仅是包的标识,还可在其中定义 __all__ 变量,指定 from 包名 import * 时要导入的模块,实现批量导入:
__all__ = ["module1" , "module2" ]
之后在主文件中可通过 from my_package import * 导入 module1 和 module2。
4.3 模块的搜索路径 Python 导入模块时,会按以下顺序搜索模块文件:
当前执行文件所在的目录;
Python 的内置模块目录;
第三方模块安装目录(如 Anaconda 的 site-packages);
环境变量 PYTHONPATH 指定的目录。
可通过 sys.path 查看 Python 的模块搜索路径:
import sys
print (sys.path)
五、总结 本文系统讲解了 Python 面向对象编程的核心知识,从基础的类与对象,到核心的封装、继承、多态三大特性,再到进阶的魔术方法和模块化编程的模块与包,核心要点总结如下:
类与对象 :类是模板,对象是实例;类包含属性(类属性 / 实例属性)和方法(实例方法 / 类方法 / 静态方法),self 代表实例本身,cls 代表类本身。
封装 :通过双下划线和 property 装饰器隐藏内部细节,对外提供公共接口,保证数据安全;
继承 :子类继承父类的属性和方法,通过 super() 调用父类方法,可重写方法实现扩展,实现代码复用;
多态 :基于继承和方法重写,同一个接口作用在不同对象上产生不同结果,让代码更灵活;
魔术方法 :双下划线开头结尾的特殊方法,自动触发,可自定义对象的行为(如打印、运算);
模块与包 :模块是 .py 文件,包是含 __init__.py 的文件夹,通过 import 导入,实现代码的模块化和高维护。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online