当前位置:首页>python>从零开始学python-封装

从零开始学python-封装

  • 2026-09-02 20:12:27
从零开始学python-封装

Hi~新朋友,记得点上面蓝字(网虫root)关注哟~

前言:

   封装是面向对象编程的三大特性之一(另外两个是继承和多态)。它的核心思想是将数据(属性)和操作数据的方法(行为)绑定在一起,形成一个独立的单元——类。同时,封装还隐藏了对象的内部实现细节,仅对外提供有限的公共接口,从而保护数据的完整性和安全性。

1. 什么是封装?

简单来说,封装就像是一个黑盒子:外部代码不需要知道内部是如何工作的,只需要通过公开的方法来使用对象即可。

2. 为什么需要封装?

  • 数据保护:防止外部代码直接修改对象的内部状态,避免产生不可预期的错误。

  • 简化接口:只暴露必要的功能,降低使用复杂度。

  • 提高可维护性:内部实现可以自由修改,只要对外接口不变,就不会影响其他代码。

  • 模块化:将相关的数据和方法组织在一起,使代码结构更清晰。

3. Python中的封装实现方式

Python并没有像Java那样严格的访问控制关键字(如private、protected),而是通过命名约定和属性装饰器来实现封装。

3.1 公有属性/方法

默认情况下,Python类中的属性和方法都是公有的,可以直接通过对象访问。

class Dog:    def __init__(self, name):        self.name = name   # 公有属性    def bark(self):        # 公有方法        print(f"{self.name} is barking!")d = Dog("Buddy")print(d.name)   # 直接访问d.bark()

3.2 使用命名约定表示“保护”成员

单下划线前缀 _name:这是一种约定,表示该属性或方法是“受保护的”,建议仅在类内部或子类中使用。但Python并不会阻止外部访问,它只是一种提示。

class Student:    def __init__(self, name, score):        self.name = name        self._score = score   # 约定为保护属性    def _study(self):         # 约定为保护方法        print(f"{self.name} is studying.")s = Student("Tom", 90)print(s._score)   # 仍然可以访问,但强烈不建议s._study()        # 同样可以调用

3.3 使用双下划线实现“私有”成员(名称修饰)

双下划线前缀 __name:当属性或方法以双下划线开头时,Python会对其进行名称修饰(name mangling),即在内部将名字改为 _类名__name 的形式,从而避免在子类中被意外覆盖。这实现了类似私有成员的效果,但并不是绝对安全(仍然可以通过修改后的名字访问)。

class BankAccount:    def __init__(self, owner, balance):        self.owner = owner        self.__balance = balance   # 私有属性    def __secret_method(self):     # 私有方法        print("This is a secret.")    def get_balance(self):        return self.__balanceacc = BankAccount("Alice", 1000)print(acc.get_balance())   # 正确:通过公共方法获取# print(acc.__balance)     # 错误:直接访问私有属性会引发 AttributeError# acc.__secret_method()    # 同样错误# 但可以通过名称修饰后的名字强制访问(不推荐)print(acc._BankAccount__balance)   # 输出 1000acc._BankAccount__secret_method()  # 输出 "This is a secret."

3.4 使用 @property 装饰器实现属性控制

@property 可以将一个方法当作属性来访问,同时可以定义对应的 setter 和 deleter 方法,从而在获取、设置或删除属性时添加额外的逻辑(如数据验证、权限检查)。

  • @property:将方法变为属性,调用时无需加括号。

  • @<属性名>.setter:定义设置属性时的行为。

  • @<属性名>.deleter:定义删除属性时的行为。

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, value):        """设置年龄,并进行验证"""        if value < 0:            raise ValueError("年龄不能为负数")        self.__age = value    @age.deleter    def age(self):        """删除年龄属性(谨慎使用)"""        print("年龄属性被删除")        del self.__age    def display(self):        print(f"姓名: {self.name}, 年龄: {self.__age}")# 使用示例p = Person("张三", 25)print(p.age)      # 通过 property 获取,输出 25p.age = 26        # 通过 setter 修改p.display()       # 输出: 姓名: 张三, 年龄: 26# p.age = -5      # 抛出 ValueError: 年龄不能为负数del p.age         # 触发 deleter,输出 "年龄属性被删除"

4. 封装涉及的语法总结

语法
说明
class ClassName:
定义类
def __init__(self, ...):
构造函数,初始化对象属性
self.attribute = value
定义实例属性
_attribute
单下划线开头,约定为“保护”成员,外部仍可访问,但应视为私有
__attribute
双下划线开头,触发名称修饰(变成_ClassName__attribute),实现“私有”
@property
将方法转换为属性,用于获取值
@attribute.setter
定义设置属性值的方法
@attribute.deleter
定义删除属性值的方法

5. 注意事项

  • 双下划线实现的“私有”并不是绝对安全的,Python 只是通过名称修饰让直接访问变得困难,但并非不可能。真正的封装依赖于程序员的自觉和约定。

  • 单下划线的“保护”成员是纯粹的约定,Python 解释器不会做任何限制,但 IDE 和代码检查工具可能会给出警告。

  • 使用 @property 可以在不改变外部调用方式的前提下,为属性增加访问控制逻辑,是 Python 中实现封装的推荐方式。

6. 总结

封装是面向对象编程中保护数据、隐藏复杂性的重要手段。在 Python 中,虽然没有强制性的访问控制,但通过命名约定和 property 装饰器,可以优雅地实现封装,提高代码的健壮性和可维护性。

【微语】无人扶我青云志,我自踏雪至山巅。

网虫root

期待你的

分享

点赞

在看

最新文章

随机文章