Python 面向对象编程(进阶篇)

Python作为一门支持面向对象编程(OOP)的动态语言,其面向对象特性不仅限于类的定义、实例化和基础继承。在实际开发中,尤其是构建复杂系统(如框架、库或大型应用)时,面向对象的进阶能力是提升代码可维护性、扩展性和复用性的关键。

本博客将深入探讨Python面向对象编程的进阶主题,包括属性的高级管理、方法的类型、继承的深层机制、抽象类、元类、设计模式等,并结合最佳实践和示例,帮助读者从“会用类”过渡到“用好类”,甚至“设计类”。

目录#

  1. 类的高级属性管理:@property 与描述符
    • 1.1 @property 装饰器:优雅的属性访问控制
    • 1.2 描述符(Descriptor):属性的底层实现
    • 1.3 最佳实践:何时使用属性装饰器或描述符?
  2. 方法的类型:实例方法、类方法、静态方法
    • 2.1 实例方法:默认的方法类型
    • 2.2 类方法(@classmethod):操作类本身
    • 2.3 静态方法(@staticmethod):无绑定的工具方法
    • 2.4 实践:方法类型的选择场景
  3. 继承与多态的进阶:MRO与多重继承
    • 3.1 方法解析顺序(MRO):Python如何查找方法?
    • 3.2 多重继承与钻石问题(Diamond Problem)
    • 3.3 最佳实践:避免多重继承的陷阱
  4. 抽象类与接口:ABC模块的应用
    • 4.1 抽象基类(ABC):强制子类实现方法
    • 4.2 接口模拟:Python的“鸭子类型”与显式接口
    • 4.3 实践:框架设计中的抽象类应用
  5. Mixin模式与组合设计
    • 5.1 Mixin:复用代码的轻量级方式
    • 5.2 组合(Composition)优于继承?
    • 5.3 实践:Mixin与组合的结合使用
  6. 元类(Metaclass):类的“类”
    • 6.1 理解元类:type 与自定义元类
    • 6.2 元类的应用场景:ORM、单例、API验证
    • 6.3 最佳实践:谨慎使用元类
  7. 设计模式在Python中的实现
    • 7.1 单例模式(Singleton):全局唯一实例
    • 7.2 工厂模式(Factory):对象创建的封装
    • 7.3 观察者模式(Observer):事件驱动的设计
    • 7.4 实践:设计模式的Pythonic实现
  8. 对象的序列化与持久化
    • 8.1 pickle:Python对象的二进制序列化
    • 8.2 JSON序列化:跨平台的数据交换
    • 8.3 最佳实践:序列化的安全与性能
  9. 面向对象的最佳实践:SOLID与代码设计
    • 9.1 SOLID原则:单一职责、开闭、里氏替换等
    • 9.2 命名规范与代码风格
    • 9.3 封装、解耦与可测试性

1. 类的高级属性管理:@property 与描述符#

1.1 @property 装饰器:优雅的属性访问控制#

在Python中,直接暴露类的属性可能导致数据的不安全或不符合业务逻辑(如年龄不能为负数)。@property 允许我们将方法伪装成属性,实现对属性的“读、写、删”控制,同时保持调用的简洁性。

示例:温度转换的属性控制#

class Celsius:
    def __init__(self, temperature=0):
        self._temperature = temperature  # 私有属性(约定,非强制)
 
    @property
    def temperature(self):
        print("获取温度...")
        return self._temperature
 
    @temperature.setter
    def temperature(self, value):
        if value < -273.15:
            raise ValueError("温度不能低于绝对零度!")
        print("设置温度...")
        self._temperature = value
 
    @temperature.deleter
    def temperature(self):
        print("删除温度属性...")
        del self._temperature
 
# 使用示例
c = Celsius(25)
print(c.temperature)  # 调用 getter
c.temperature = 30    # 调用 setter
del c.temperature     # 调用 deleter

常见实践:#

  • 对需要计算的属性(如面积=长×宽)使用@property,避免重复计算或暴露内部状态。
  • 对需要验证的属性(如邮箱格式、数值范围)使用@setter进行合法性检查。

最佳实践:#

  • 属性名与内部存储变量名区分(如temperature vs _temperature),遵循“私有”约定(单下划线)。
  • 避免在@property中包含复杂逻辑(如网络请求、大计算),否则会影响属性访问的性能感知。

1.2 描述符(Descriptor):属性的底层实现#

@property 本质上是描述符协议的语法糖。描述符是实现了 __get____set____delete__ 方法的类,用于管理另一个类的属性访问。

示例:自定义温度描述符#

class TemperatureDescriptor:
    def __get__(self, instance, owner):
        print(f"从 {instance} 中获取属性,类是 {owner}")
        return instance.__dict__[self.name]  # 避免递归,直接操作__dict__
 
    def __set__(self, instance, value):
        if value < -273.15:
            raise ValueError("温度不能低于绝对零度!")
        instance.__dict__[self.name] = value
 
    def __set_name__(self, owner, name):  # Python 3.6+ 新增,自动绑定属性名
        self.name = name
 
class Celsius:
    temperature = TemperatureDescriptor()  # 描述符实例作为类属性
 
    def __init__(self, temperature=0):
        self.temperature = temperature  # 触发 __set__
 
# 使用示例
c = Celsius(25)
print(c.temperature)  # 触发 __get__
c.temperature = 30    # 触发 __set__

常见实践:#

  • 框架或库开发中,使用描述符统一管理属性的访问逻辑(如Django的模型字段)。
  • 实现类型检查(如确保属性为整数)、缓存属性(如functools.cached_property)。

最佳实践:#

  • 描述符类应独立,便于复用(如多个类的属性需要相同的验证逻辑)。
  • 避免在__get__/__set__中过度耦合实例逻辑,保持描述符的通用性。

1.3 何时使用属性装饰器或描述符?#

场景@property描述符(Descriptor)
复用性仅适用于单个类的属性管理可在多个类中复用(如温度描述符)
实现复杂度简单,通过装饰器快速实现稍复杂,需实现协议方法
适用场景单个类的属性验证、计算属性跨类的属性管理、框架级属性控制

建议:简单的类内属性控制用@property;需要复用的属性逻辑(如多个类的字段验证)用描述符。

2. 方法的类型:实例方法、类方法、静态方法#

Python类中的方法分为三种类型,它们的区别在于参数绑定调用方式

2.1 实例方法:默认的方法类型#

实例方法的第一个参数是self(实例本身),必须通过实例调用,用于操作实例的状态。

class Person:
    def __init__(self, name):
        self.name = name
 
    def say_hello(self):  # 实例方法
        print(f"你好,我是 {self.name}")
 
p = Person("Alice")
p.say_hello()  # 必须通过实例调用

2.2 类方法(@classmethod):操作类本身#

类方法的第一个参数是cls(类本身),通过@classmethod装饰,可通过类或实例调用,常用于创建类的备选构造器

示例:日期的备选构造器#

class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day
 
    @classmethod
    def from_string(cls, date_str):  # 类方法,cls绑定到Date类
        year, month, day = map(int, date_str.split('-'))
        return cls(year, month, day)  # 创建Date实例
 
# 使用
d = Date.from_string("2023-10-01")
print(d.year, d.month, d.day)

常见实践:#

  • 类方法作为工厂方法,根据不同输入创建类实例(如从JSON、字符串解析)。
  • 在继承中,类方法可返回子类的实例(多态的构造器)。

2.3 静态方法(@staticmethod):无绑定的工具方法#

静态方法无默认参数(无selfcls),通过@staticmethod装饰,本质是类命名空间下的函数,与类和实例无关,仅用于逻辑上的归类。

class MathUtils:
    @staticmethod
    def add(a, b):
        return a + b
 
# 调用方式:类或实例均可
print(MathUtils.add(3, 5))
mu = MathUtils()
print(mu.add(4, 6))

常见实践:#

  • 工具函数(如数据转换、格式验证)放在相关类的静态方法中,提高代码内聚性。
  • 静态方法不依赖类或实例的状态,因此可独立测试。

2.4 实践:方法类型的选择场景#

方法类型绑定参数调用方式适用场景
实例方法self实例调用操作实例属性、实例特有逻辑
类方法cls类/实例调用类级别的操作、备选构造器
静态方法类/实例调用工具函数、无状态逻辑

建议

  • 需要访问实例属性?用实例方法。
  • 需要创建实例或操作类?用类方法。
  • 纯工具函数,与类/实例无关?用静态方法。

3. 继承与多态的进阶:MRO与多重继承#

Python支持多重继承,但需理解**方法解析顺序(MRO)**以避免歧义。

3.1 方法解析顺序(MRO):Python如何查找方法?#

MRO定义了类在多重继承时,方法的查找顺序。可通过__mro__属性或mro()方法查看。

示例:线性化的MRO#

class A:
    def show(self):
        print("A")
 
class B(A):
    def show(self):
        print("B")
 
class C(A):
    def show(self):
        print("C")
 
class D(B, C):
    pass
 
# 查看MRO
print(D.mro())  # 输出: [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
 
d = D()
d.show()  # 输出 B(因为B在MRO中先于C)

Python的MRO基于C3线性化算法,保证:

  1. 子类永远在父类之前。
  2. 同一父类在MRO中只出现一次。
  3. 基类的声明顺序影响MRO(如D(B, C)中B先于C)。

3.2 多重继承与钻石问题(Diamond Problem)#

当继承结构形成“钻石”(如ABC的父类,D继承BC),方法调用可能出现歧义。MRO通过线性化解决了这个问题。

示例:钻石继承#

class A:
    def show(self):
        print("A")
 
class B(A):
    def show(self):
        print("B")
        super().show()  # 调用父类(A)的方法
 
class C(A):
    def show(self):
        print("C")
        super().show()  # 调用父类(A)的方法
 
class D(B, C):
    def show(self):
        print("D")
        super().show()  # 调用MRO中的下一个类(B)
 
d = D()
d.show() 
# 输出:
# D
# B
# C
# A

在D的MRO中,顺序是D→B→C→A,因此super().show()在B中调用C的show,在C中调用A的show,实现了“钻石”结构的正确方法解析。

3.3 最佳实践:避免多重继承的陷阱#

多重继承虽强大,但易导致代码复杂、难以维护。

常见陷阱:#

  • 命名冲突:多个父类有同名方法,MRO顺序可能不符合预期。
  • 状态不一致:多个父类修改实例属性,导致逻辑混乱。

最佳实践:#

  • 优先使用单继承,配合Mixin(轻量级多继承)。
  • 使用super()而非直接调用父类(如B.show(self)),确保MRO的正确性。
  • 避免“深度”多重继承(继承链过长),保持继承结构扁平。

4. 抽象类与接口:ABC模块的应用#

Python是动态类型语言,依赖“鸭子类型”(只要走起来像鸭子,就是鸭子)。但在框架设计中,有时需要强制子类实现特定方法,这就需要抽象类。

4.1 抽象基类(ABC):强制子类实现方法#

通过abc模块的ABCMeta元类和abstractmethod装饰器,定义抽象类(不能实例化),子类必须实现所有抽象方法。

示例:图形的抽象基类#

from abc import ABC, abstractmethod
 
class Shape(ABC):  # 继承ABC,指定元类为ABCMeta
    @abstractmethod
    def area(self):
        """计算面积的抽象方法,子类必须实现"""
        pass
 
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
 
    def area(self):  # 必须实现area方法
        return 3.14 * self.radius **2
 
class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
 
    def area(self):
        return self.width * self.height
 
# 错误示例:不实现抽象方法
class InvalidShape(Shape):
    pass
 
# s = Shape()  # 报错:Cannot instantiate abstract class Shape with abstract method area
# ishape = InvalidShape()  # 报错:Cannot instantiate abstract class InvalidShape with abstract method area
 
# 正确使用
c = Circle(5)
print(c.area())  # 78.5

常见实践:#

  • 框架或库中定义抽象接口(如数据库操作的DBProvider),强制子类实现核心方法。
  • 结合register方法,将非继承的类“注册”为抽象类的子类(扩展鸭子类型)。

示例:注册非继承类为抽象子类#

@Shape.register
class Square:  # 未继承Shape
    def __init__(self, side):
        self.side = side
 
    def area(self):
        return self.side **2
 
s = Square(4)
print(isinstance(s, Shape))  # True,因为被注册为Shape的子类

4.2 接口模拟:Python的“鸭子类型”与显式接口#

Python没有显式的“接口”关键字,但可通过抽象类模拟接口(仅定义方法签名,无实现)。

示例:支付接口#

class Payment(ABC):
    @abstractmethod
    def pay(self, amount):
        pass
 
class WeChatPay(Payment):
    def pay(self, amount):
        print(f"微信支付 {amount} 元")
 
class AliPay(Payment):
    def pay(self, amount):
        print(f"支付宝支付 {amount} 元")

最佳实践:#

  • 抽象类用于核心逻辑的约束(如框架的插件接口)。
  • 鸭子类型用于灵活的业务逻辑(如函数接受任何实现__len__的对象)。
  • 避免过度使用抽象类,保持Python的动态性优势。

5. Mixin模式与组合设计#

Mixin是一种轻量级多继承,通过混入(mixin)类,为子类添加额外功能,而不影响主继承链。

5.1 Mixin:复用代码的轻量级方式#

Mixin类通常不单独使用,而是作为“混入”类,为其他类提供方法。命名习惯上以Mixin结尾。

示例:日志功能的Mixin#

class LogMixin:
    def log(self, message):
        print(f"[LOG] {message}")
 
class User:
    def __init__(self, name):
        self.name = name
 
class AdminUser(User, LogMixin):  # 混入LogMixin
    def delete_account(self, user):
        self.log(f"删除用户 {user.name}")
        # 其他删除逻辑
 
admin = AdminUser("Admin")
admin.delete_account(User("Alice"))  # 输出: [LOG] 删除用户 Alice

常见实践:#

  • Mixin类无状态(不定义__init__或实例属性),仅提供方法。
  • Mixin类名清晰表达功能(如LogMixinSerializableMixin)。

5.2 组合(Composition)优于继承?#

继承是“是一个”(is-a)关系,组合是“有一个”(has-a)关系。在复杂系统中,组合更灵活,避免继承的紧耦合。

示例:汽车的组合设计#

class Engine:
    def start(self):
        print("引擎启动")
 
class Wheel:
    def rotate(self):
        print("车轮旋转")
 
class Car:
    def __init__(self):
        self.engine = Engine()  # 组合Engine
        self.wheels = [Wheel() for _ in range(4)]  # 组合Wheel
 
    def drive(self):
        self.engine.start()
        for wheel in self.wheels:
            wheel.rotate()
        print("汽车行驶中...")
 
car = Car()
car.drive()

最佳实践:#

  • 当关系是“有一个”时,用组合(如汽车有引擎、车轮)。
  • 当关系是“是一个”且需要复用方法时,用继承+Mixin。
  • 组合的对象可动态替换(如更换引擎类型),而继承的父类固定。

5.3 实践:Mixin与组合的结合使用#

在实际开发中,常结合两者优势:

  • 用Mixin提供通用方法(如日志、序列化)。
  • 用组合管理核心组件(如数据库连接、第三方服务)。

6. 元类(Metaclass):类的“类”#

元类是创建类的“类”,Python中所有类的默认元类是type。通过自定义元类,可在类创建时修改其属性、方法或行为。

6.1 理解元类:type 与自定义元类#

类的创建过程:class MyClass: ... 等价于 MyClass = type(classname, bases, dict),其中:

  • classname:类名(字符串)
  • bases:父类元组
  • dict:类的命名空间(方法、属性)

示例:用type动态创建类#

# 动态创建类
def say_hello(self):
    print(f"你好,我是 {self.name}")
 
MyClass = type("MyClass", (), {
    "name": "动态类",
    "say_hello": say_hello
})
 
obj = MyClass()
obj.say_hello()  # 输出: 你好,我是 动态类

自定义元类:#

class MyMeta(type):
    def __new__(cls, name, bases, dct):
        # 类创建前的修改:自动添加version属性
        dct["version"] = "1.0"
        # 还可以修改方法、校验属性等
        return super().__new__(cls, name, bases, dct)
 
class MyClass(metaclass=MyMeta):
    pass
 
print(MyClass.version)  # 输出: 1.0

6.2 元类的应用场景:ORM、单例、API验证#

元类的强大在于拦截类的创建过程,常见场景:

  • ORM框架:自动将类属性映射到数据库字段(如Django的Model、SQLAlchemy的DeclarativeBase)。
  • 单例模式:确保类只有一个实例(通过元类控制__call__方法)。
  • API验证:类创建时校验方法签名、属性类型。

示例:ORM的元类简化#

class ModelMeta(type):
    def __new__(cls, name, bases, dct):
        # 提取类属性中的字段(如title, content)
        fields = {}
        for attr, value in dct.items():
            if isinstance(value, Field):  # 假设Field是字段基类
                fields[attr] = value
        dct["__fields__"] = fields
        return super().__new__(cls, name, bases, dct)
 
class Field:
    def __init__(self, type_):
        self.type = type_
 
class User(metaclass=ModelMeta):
    name = Field(str)
    age = Field(int)
 
print(User.__fields__)  # 输出: {'name': <__main__.Field object at ...>, 'age': <__main__.Field object at ...>}

6.3 最佳实践:谨慎使用元类#

元类会增加代码复杂度,除非必要,否则避免使用:

  • 简单的类修改(如添加属性)可通过类装饰器实现。
  • 复杂的框架级逻辑(如ORM)才考虑元类。
  • 文档中明确说明元类的作用,便于团队协作。

7. 设计模式在Python中的实现#

设计模式是解决常见问题的经典方案,Python的动态特性使其实现更简洁。

7.1 单例模式(Singleton):全局唯一实例#

确保类只有一个实例,常用于配置管理器、数据库连接池。

实现方式1:元类#

class SingletonMeta(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]
 
class Singleton(metaclass=SingletonMeta):
    pass
 
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # True

实现方式2:装饰器#

def singleton(cls):
    instances = {}
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper
 
@singleton
class MySingleton:
    pass
 
ms1 = MySingleton()
ms2 = MySingleton()
print(ms1 is ms2)  # True

最佳实践:#

  • 单例的生命周期与应用一致,避免内存泄漏(如持有大量状态)。
  • 多线程环境下需加锁(如threading.Lock),确保实例唯一。

7.2 工厂模式(Factory):对象创建的封装#

将对象的创建逻辑封装,根据输入返回不同类型的实例,解耦创建与使用。

示例:图形工厂#

class Circle:
    def draw(self):
        print("画圆形")
 
class Rectangle:
    def draw(self):
        print("画矩形")
 
class ShapeFactory:
    @staticmethod
    def create_shape(shape_type):
        if shape_type == "circle":
            return Circle()
        elif shape_type == "rectangle":
            return Rectangle()
        else:
            raise ValueError(f"不支持的图形类型:{shape_type}")
 
# 使用
factory = ShapeFactory()
circle = factory.create_shape("circle")
circle.draw()  # 画圆形

最佳实践:#

  • 工厂方法返回抽象产品(如Shape),而非具体类,便于扩展。
  • 复杂创建逻辑(如依赖注入、配置解析)适合用工厂模式。

7.3 观察者模式(Observer):事件驱动的设计#

对象(主题)维护观察者列表,状态变化时通知所有观察者。

示例:发布-订阅系统#

class Subject:
    def __init__(self):
        self.observers = []
 
    def attach(self, observer):
        self.observers.append(observer)
 
    def detach(self, observer):
        self.observers.remove(observer)
 
    def notify(self, message):
        for observer in self.observers:
            observer.update(message)
 
class Observer:
    def __init__(self, name):
        self.name = name
 
    def update(self, message):
        print(f"{self.name} 收到通知:{message}")
 
# 使用
subject = Subject()
observer1 = Observer("张三")
observer2 = Observer("李四")
 
subject.attach(observer1)
subject.attach(observer2)
subject.notify("有新文章发布!")
 
subject.detach(observer1)
subject.notify("文章已更新!")

最佳实践:#

  • 观察者与主题松耦合(通过接口或抽象类交互)。
  • 避免循环通知(观察者修改主题状态,导致无限循环)。

7.4 实践:设计模式的Pythonic实现#

Python的动态特性允许更简洁的实现:

  • 单例可用模块级变量(Python模块天然单例)。
  • 工厂模式可用类方法装饰器,而非单独的工厂类。
  • 观察者模式可用回调函数(如listeners列表存储函数)。

8. 对象的序列化与持久化#

将Python对象转换为字节或文本(序列化),便于存储或网络传输,再恢复为对象(反序列化)。

8.1 pickle:Python对象的二进制序列化#

pickle可序列化几乎所有Python对象(包括自定义类、实例、函数),但仅能在Python中使用,且存在安全风险(反序列化不可信数据可能执行恶意代码)。

示例:序列化与反序列化#

import pickle
 
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})"
 
# 序列化
person = Person("Bob", 30)
with open("person.pkl", "wb") as f:
    pickle.dump(person, f)
 
# 反序列化
with open("person.pkl", "rb") as f:
    loaded_person = pickle.load(f)
    print(loaded_person)  # 输出: Person(name=Bob, age=30)

最佳实践:#

  • 仅在可信环境中使用pickle(如内部数据存储)。
  • 对包含敏感数据的对象,避免序列化(或加密后序列化)。

8.2 JSON序列化:跨平台的数据交换#

JSON是轻量级文本格式,支持基本类型(字典、列表、字符串等),但需自定义类的序列化逻辑(通过json.JSONEncoderjson.loadsobject_hook)。

示例:自定义类的JSON序列化#

import json
 
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
 
# 自定义编码器
class PersonEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, Person):
            return {"name": o.name, "age": o.age, "__type__": "Person"}
        return super().default(o)
 
# 自定义解码器
def person_decoder(dct):
    if "__type__" in dct and dct["__type__"] == "Person":
        return Person(dct["name"], dct["age"])
    return dct
 
# 序列化
person = Person("Alice", 25)
json_str = json.dumps(person, cls=PersonEncoder)
print(json_str)  # 输出: {"name": "Alice", "age": 25, "__type__": "Person"}
 
# 反序列化
loaded_person = json.loads(json_str, object_hook=person_decoder)
print(loaded_person.name, loaded_person.age)  # Alice 25

最佳实践:#

  • 跨平台或公开API使用JSON,兼容性更好。
  • 对复杂对象,定义清晰的序列化/反序列化规则(如__type__标记类类型)。

8.3 最佳实践:序列化的安全与性能#

  • 安全:避免反序列化不可信数据(如pickle__reduce__方法可被利用)。
  • 性能:大对象序列化使用jsonmsgpack(二进制JSON),避免pickle的大开销。
  • 版本兼容:序列化时包含版本信息,便于后续解析。

9. 面向对象的最佳实践:SOLID与代码设计#

SOLID是面向对象设计的五大原则,帮助创建可维护、可扩展的代码。

9.1 SOLID原则:#

  1. 单一职责原则(SRP):一个类只负责一项职责。

    • 示例:User类只处理用户信息,UserService处理业务逻辑,UserRepository处理数据库操作。
  2. 开闭原则(OCP):对扩展开放,对修改关闭。

    • 示例:通过继承或组合扩展功能,而非修改现有类(如添加新的支付方式,扩展Payment子类,而非修改Payment类)。
  3. 里氏替换原则(LSP):子类可替换父类,且不破坏程序逻辑。

    • 示例:Rectangle子类的set_width/set_height逻辑不应破坏Shape父类的面积计算。
  4. 接口隔离原则(ISP):客户端不应依赖不需要的接口。

    • 示例:将大接口拆分为小接口(如FileReaderFileWriter,而非FileIO)。
  5. 依赖倒置原则(DIP):依赖抽象,而非具体实现。

    • 示例:函数接受Shape抽象类,而非具体的CircleRectangle

9.2 命名规范与代码风格#

  • 类名:大驼峰(UserManager),清晰表达职责。
  • 方法名:小写+下划线(get_user),动词开头(create_update_delete_)。
  • 属性名:小写+下划线(user_name),保护属性用单下划线(_password),私有属性用双下划线(__secret,触发名称修饰)。
  • 遵循PEP8规范,保持代码风格一致。

9.3 封装、解耦与可测试性#

  • 封装:隐藏内部实现,暴露简洁接口(如@property控制属性访问)。
  • 解耦:类之间依赖抽象(如DB接口),而非具体实现(如MySQLDB),便于替换和测试。
  • 可测试性:类职责单一,依赖可注入(如构造函数传入DB实例),便于单元测试。

参考#

  1. Python官方文档:Classesabcpickle
  2. 《Fluent Python》( Luciano Ramalho ):深入Python面向对象与元编程。
  3. 《Design Patterns: Elements of Reusable Object-Oriented Software》:经典设计模式指南。
  4. Real Python教程:Python MetaclassesPython Descriptors
  5. SOLID原则详解:Refactoring.Guru

通过本博客的学习,相信你已掌握Python面向对象编程的进阶技巧。从属性管理到元类,从设计模式到最佳实践,这些知识将帮助你构建更优雅、更强大的Python程序。实践是掌握的关键,建议结合实际项目,尝试将这些技巧应用到代码中,逐步提升面向对象设计能力!