面向对象编程进阶
基础教学 1 min read

面向对象编程进阶

Blog Author

面向对象编程进阶

本节内容聚焦 Python 面向对象编程的高级特性,包括属性可见性、动态属性、静态方法与类方法、property 装饰器、继承与多态等关键机制。我们将以教学方式讲解这些知识的原理、使用场景以及最佳实践。


一、属性可见性与访问控制

🔍 概念解析

Python 没有像 Java、C++ 等语言那样的严格访问控制关键字(如 privateprotectedpublic),但可通过 命名规范 实现类似的可见性控制:

  • __属性名(双下划线):表示私有成员(private),类外不可访问,Python 实际上会做名字改写(name mangling)成 _类名__属性名
  • _属性名(单下划线):表示受保护成员(protected),不是强制私有,通常只用于类及其子类。
  • 属性名:表示公有成员(public),可随意访问。

✅ 使用建议

  • 推荐:优先使用 _name 来提示访问风险,而非强制隐藏。
  • 私有变量仅在确实需要隐藏或防止误用时使用。

📌 示例

class Student:
    def __init__(self, name, age):
        self.__name = name  # 私有变量
        self._age = age     # 受保护变量


    def greet(self):
        print(f'Hello, I am {self.__name}, {self._age} years old.')

反例print(stu.__name) 会抛出 AttributeError,但可以通过 stu._Student__name 访问。


二、动态属性与 __slots__

💡 动态属性的优势

Python 的对象天生支持“运行时扩展”,可以动态添加或修改属性:

stu = Student("Alice", 20)
stu.gender = "female"  # 动态添加属性

这给开发带来极大灵活性,比如在 ORM 框架中根据数据库动态扩展模型字段。

⚠️ 问题:内存与滥用风险

  • 动态添加属性会占用额外内存(因为每个实例有独立 __dict__)。
  • 如果类的设计初衷是结构稳定,就可能被误用或滥用。

✅ 最佳实践:使用 __slots__ 限定属性

class Student:
    __slots__ = ('name', 'age')


    def __init__(self, name, age):
        self.name = name
        self.age = age

使用场景:

  • 需要创建大量实例(节省内存)
  • 希望限制属性名(避免错误扩展)

三、静态方法与类方法

🔧 静态方法 @staticmethod

用于那些不依赖于对象或类状态的方法,类似“工具函数”:

class MathUtils:
    @staticmethod
    def add(a, b):
        return a + b

🏷 类方法 @classmethod

  • 绑定类对象 cls 而非实例对象 self
  • 通常用于工厂方法或访问类级别数据
class Book:
    count = 0


    def __init__(self, title):
        self.title = title
        Book.count += 1


    @classmethod
    def how_many_books(cls):
        return cls.count

✅ 使用建议

场景 方法类型 推荐修饰器
与实例状态有关 实例方法 def method(self)
与类状态有关 类方法 @classmethod
与类和实例都无关 静态方法 @staticmethod

四、@property 属性访问器

🎯 目的

让“方法”看起来像“属性”一样访问,从而隐藏实现细节,提供更自然的接口

class Circle:
    def __init__(self, radius):
        self._radius = radius


    @property
    def area(self):
        return 3.1416 * self._radius ** 2

调用时不加括号:

c = Circle(3)
print(c.area)  # 输出面积,不是方法调用

🛠 应用场景

  • 只读属性(如计算值)
  • 延迟计算
  • 控制访问逻辑(比如校验或缓存)

✅ 最佳实践

可配合 @property.setter 实现可控赋值:

@property
def radius(self):
    return self._radius


@radius.setter
def radius(self, value):
    if value <= 0:
        raise ValueError("半径必须为正数")
    self._radius = value

五、继承与多态

🧬 继承

  • 通过继承复用代码,减少重复
  • 使用 super() 调用父类方法
class Person:
    def eat(self): print("吃饭")


class Student(Person):
    def study(self): print("学习")

🌀 多态

调用相同方法,表现不同行为

def do_sleep(person):
    person.sleep()


class Teacher(Person):
    def sleep(self): print("老师正在睡觉")


class Student(Person):
    def sleep(self): print("学生正在睡觉")


do_sleep(Teacher())
do_sleep(Student())

输出根据传入对象类型而变 —— 这就是多态性

✅ 实用场景

  • 构建通用接口(如 do_something(obj)
  • 框架设计中解耦对象行为
  • 实现插件机制或策略模式

六、最佳实践总结

特性 使用建议 实用场景
可见性 默认公开,特殊情况用私有或受保护 框架底层、防止误用
动态属性 默认允许,结构固定用 __slots__ ORM、配置类
静态方法 无状态工具方法 工具类、验证器
类方法 类级别逻辑,如工厂函数 创建对象、访问类变量
@property 提供只读或可控访问 计算属性、封装逻辑
继承 抽象出公共逻辑 子类特化
多态 设计统一接口,行为差异由子类实现 插件式架构、策略模式

七、总结与延伸阅读

Python 的面向对象编程为高可读性、模块化和可扩展性提供了良好的工具支持。在进阶开发中,应根据业务需求合理选择封装粒度、类层级、访问方式及方法类型,避免滥用 OO 特性导致结构臃肿。

📚 推荐进一步学习:

  • 《Python源码剖析》:深入理解 Python 类模型和方法解析顺序(MRO)
  • 《设计模式》:理解多态与继承在设计模式中的核心作用
  • 《流畅的Python》:掌握高级属性控制、描述符、元类等高级 OO 技巧

如需进一步讲解「多态实现方式」「抽象类与接口」等更深层次内容,请继续提问。