在前三个阶段,我们写的代码都是“面向过程”的:数据是一堆变量,操作是一堆函数,按顺序执行。这没问题,但项目大了就会乱。第四阶段,我们学习 面向对象编程(OOP),把数据和操作数据的函数打包成“对象”,让代码更贴近现实世界,更好组织。同时,我们还会解锁一些 装饰器、生成器 等高级武器,让你的代码更简洁、更强大。
一、面向对象编程(OOP):用“对象”思考
1. 类和对象:从“图纸”到“实物”
- 类(Class):就像一张设计图纸,定义了某种东西应该有什么(属性)和能做什么(方法)。
- 对象(Object):根据图纸造出来的具体实物。
举个例子:
# 图纸:汽车设计图classCar:def__init__(self, brand, color):self.brand = brand # 属性:品牌self.color = color # 属性:颜色self.speed = 0# 属性:速度def drive(self): # 方法:开车self.speed = 60print(f"{self.color}的{self.brand}正在以{self.speed}km/h行驶")# 实物:根据图纸造出来的具体汽车my_car = Car("特斯拉", "黑色")your_car = Car("比亚迪", "白色")my_car.drive() # 输出:黑色的特斯拉正在以60km/h行驶
self 是个关键:它代表“这个对象自己”。在类的方法里,想访问对象的属性或调用其他方法,都得通过 self.xxx。
2. 封装:把细节“藏”起来
封装就是把数据和对数据的操作打包在一起,对外只暴露必要的接口,隐藏内部细节。在Python里,我们主要靠命名约定来实现:
- 公开属性/方法:正常命名,如 speed、drive()
- 受保护属性/方法:单下划线开头,如 _internal_data(约定俗成,告诉别人“别直接碰”)
- 私有属性/方法:双下划线开头,如 __secret_key(Python会改名,防止意外访问)
Python
classBankAccount:def__init__(self, owner, balance):self.owner = owner # 公开self._balance = balance # 受保护(约定)self.__password = "123456"# 私有(会被改名成 _BankAccount__password)def deposit(self, amount): # 公开接口if amount > 0:self._balance += amountprint(f"存款成功,余额:{self._balance}")else:print("存款金额必须大于0")# 使用account = BankAccount("小明", 1000)account.deposit(500) # ✅ 通过公开方法操作print(account.owner) # ✅ 可以访问公开属性# print(account._balance) # ⚠️ 能访问,但不建议(约定)# print(account.__password) # ❌ 会报错,访问不到
3. 继承:子承父业,还能拓展
继承让一个类(子类)可以继承另一个类(父类)的属性和方法,实现代码复用和扩展。
Python
classAnimal: # 父类(基类)def__init__(self, name):self.name = namedef eat(self):print(f"{self.name}在吃东西")classDog(Animal): # 子类,继承Animaldef__init__(self, name, breed):super().__init__(name) # 调用父类的初始化方法self.breed = breed # 子类特有的属性def bark(self): # 子类特有的方法print(f"{self.name}汪汪叫")# 使用dog = Dog("旺财", "金毛")dog.eat() # ✅ 继承来的方法dog.bark() # ✅ 子类自己的方法
4. 多态:同一接口,不同表现
多态指不同的类可以有同名的方法,但具体实现不同。调用者不用关心具体是哪个类,只管调用。
Python
classCat(Animal):def eat(self): # 重写父类方法print(f"{self.name}优雅地吃猫粮")classBird(Animal):def eat(self): # 重写父类方法print(f"{self.name}快速地啄食")def feed_animal(animal): # 这个函数不关心具体动物类型 animal.eat()# 传入不同的对象,表现不同feed_animal(Dog("阿黄", "土狗")) # 输出:阿黄在吃东西feed_animal(Cat("咪咪")) # 输出:咪咪优雅地吃猫粮feed_animal(Bird("小翠")) # 输出:小翠快速地啄食
这就是多态:同一个 feed_animal 函数,传入不同的动物对象,会调用各自类里定义的 eat 方法。
5. 类属性、类方法和静态方法
- 类属性:属于类本身,所有实例共享。比如 Car.wheels = 4(所有汽车都有4个轮子)。
- 类方法(@classmethod):第一个参数是 cls,代表类本身。常用于创建替代构造器或操作类属性。
- 静态方法(@staticmethod):不需要 self或 cls,就是个普通函数,只是逻辑上属于这个类。
Python
classStudent: school = "第一中学"# 类属性,所有学生共享def__init__(self, name):self.name = name @classmethoddef change_school(cls, new_name): cls.school = new_name # 修改类属性print(f"学校已更名为:{cls.school}") @staticmethoddef is_valid_name(name):# 静态方法,不依赖实例或类returnisinstance(name, str) andlen(name) > 0# 使用stu1 = Student("张三")stu2 = Student("李四")print(stu1.school, stu2.school) # 都是"第一中学"Student.change_school("实验中学") # 通过类方法修改print(stu1.school) # 现在也是"实验中学"(类属性变了)print(Student.is_valid_name("")) # False
二、高级特性:让代码更优雅
1. 装饰器:给函数“穿衣服”
装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新函数。常用于给函数添加额外功能(如日志、计时、权限检查),而不修改原函数代码。
基础装饰器示例(计时器):
import timedef timer(func):def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) # 执行原函数 end = time.time()print(f"{func.__name__} 执行耗时:{end - start:.2f}秒")return resultreturn wrapper@timer # 相当于 say_hello = timer(say_hello)def say_hello(name): time.sleep(1) # 模拟耗时操作print(f"你好,{name}!")say_hello("世界")# 输出:# 你好,世界!# say_hello 执行耗时:1.00秒
装饰器语法 @timer 只是语法糖,它把下面的函数 say_hello 作为参数传给 timer,然后用返回的 wrapper 函数替换原来的 say_hello。
2. 生成器:懒加载的“数据流”
生成器是一种特殊的迭代器,它不会一次性生成所有数据,而是按需生成,节省内存。用yield 关键字定义。
Python
def count_up_to(max_num):"""生成从1到max_num的数字""" n = 1while n <= max_num:yield n # 每次yield返回一个值,并暂停在这里 n += 1# 使用for num in count_up_to(5):print(num) # 依次输出 1 2 3 4 5# 或者手动调用gen = count_up_to(3)print(next(gen)) # 1print(next(gen)) # 2print(next(gen)) # 3# print(next(gen)) # ❌ 会报错 StopIteration
应用场景:处理大文件、无限序列、流式数据。比如读一个10GB的文件,用生成器可以一行一行处理,而不是一次性全读进内存。
3. 上下文管理器(with语句):自动管理资源
用 with 语句可以确保资源(如文件、网络连接)在使用后被正确清理,即使发生异常。
Python
# 传统方式(容易忘记关闭)f = open("test.txt", "r")content = f.read()f.close() # 必须记得关闭!# with语句(自动关闭)withopen("test.txt", "r") as f: content = f.read()# 退出with块后,文件自动关闭,即使中间出错
你也可以用 @contextmanager 装饰器创建自己的上下文管理器:
from contextlib import contextmanager@contextmanagerdef tag(name):print(f"<{name}>")yield# 这里是with块内部代码执行的地方print(f"</{name}>")with tag("div"):print("Hello World")# 输出:# <div># Hello World# </div>
三、第四阶段学习清单
1.理解类和对象的关系,能自己设计简单的类
2.掌握 __init__、self 的用法,会定义实例属性和方法
3.理解封装的概念,知道 _ 和 __ 的命名约定
4.会使用继承创建子类,理解 super() 的作用
5.理解多态的概念,能写出体现多态的代码
6.区分实例属性、类属性、实例方法、类方法、静态方法
7.会使用简单的装饰器(如 @timer)给函数添加功能
8.理解生成器的概念,会用 yield 创建简单的生成器
9.熟练使用 with 语句管理文件等资源
四、小结:从“写脚本”到“设计程序”
第四阶段是思维方式的升级。面向对象让你用“对象”的视角建模现实问题,把数据和操作封装在一起,代码结构更清晰、更易维护。高级特性(装饰器、生成器、上下文管理器)则是Python提供的“语法糖”,让你用更少的代码做更多的事,写出更Pythonic(符合Python风格)的代码。
掌握了这些,你就不再是仅仅写脚本的“码农”,而是开始具备设计程序的能力。你可以:
下一阶段,我们将进入 第五阶段:生态与方向,探索Python强大的第三方库,并选择你的专精方向(Web开发、数据分析、爬虫、自动化等)。准备好进入真正的项目实战了吗?我们下一篇见!