云计算百科
云计算领域专业知识百科平台

编程与数学 02-017 Python 面向对象编程 05课题、封装

编程与数学 02-017 Python 面向对象编程 05课题、封装

  • 一、封装的核心思想
  • 二、Python 实现封装的三种方式
      • (1) 命名约定
      • (2) 使用 `@property` 控制访问
      • (3) 通过方法暴露操作
  • 三、封装的优点
  • 四、封装的常见应用场景
      • (1) 数据验证
      • (2) 只读属性
      • (3) 延迟加载(Lazy Loading)
  • 五、注意事项
  • 六、封装 vs 非封装对比
      • 非封装示例(风险高)
      • 封装示例(安全)
  • 全文总结

摘要:封装通过命名约定、@property和方法暴露三种方式隐藏实现细节,防止非法修改,简化接口;优点是数据保护、低耦合、易维护、高灵活性,适用于数据验证、只读属性与延迟加载等场景。

关键词:封装、Python、命名约定、@property、数据保护

人工智能助手:Kimi


一、封装的核心思想

  • 隐藏实现细节:只暴露必要的操作接口,内部逻辑对用户透明。
  • 数据保护:防止外部直接修改对象内部状态,避免非法操作。
  • 简化使用:用户只需知道“做什么”,无需关心“怎么做”。

二、Python 实现封装的三种方式

Python 没有严格的 private 或 protected 关键字,但通过以下约定实现封装:

(1) 命名约定

  • 公有成员:直接公开(如 name)。
  • 受保护成员:单下划线 _ 前缀(约定俗成,非强制)。
  • 私有成员:双下划线 __ 前缀(触发名称修饰,避免直接访问)。

class BankAccount:
def __init__(self, balance):
self.balance = balance # 公有属性
self._account_id = "123" # 受保护属性(约定)
self.__pin = "0000" # 私有属性(名称修饰为 _BankAccount__pin)

account = BankAccount(1000)
print(account.balance) # 正常访问:1000
print(account._account_id) # 仍可访问(但不推荐):123
print(account.__pin) # 报错!实际需访问 account._BankAccount__pin

(2) 使用 @property 控制访问

  • 将方法伪装成属性,通过 getter/setter 添加逻辑。
  • 优点:保持接口一致性,同时实现数据验证。

class Temperature:
def __init__(self, celsius):
self._celsius = celsius # 保护属性

@property
def celsius(self): # Getter
return self._celsius

@celsius.setter
def celsius(self, value): # Setter(可添加校验)
if value < 273.15:
raise ValueError("温度不能低于绝对零度!")
self._celsius = value

@property
def fahrenheit(self): # 计算属性(只读)
return self._celsius * 9/5 + 32

temp = Temperature(25)
print(temp.celsius) # 25
temp.celsius = 30 # 通过 setter 修改
print(temp.fahrenheit) # 86.0(只读属性)
temp.celsius = 300 # 触发 ValueError

(3) 通过方法暴露操作

禁止直接修改属性,强制通过方法操作数据。

class LightSwitch:
def __init__(self):
self.__is_on = False # 私有属性

def turn_on(self): # 公有方法
self.__is_on = True

def turn_off(self):
self.__is_on = False

def status(self):
return "开" if self.__is_on else "关"

switch = LightSwitch()
switch.turn_on()
print(switch.status()) # 输出: 开
# switch.__is_on = True # 报错!无法直接访问私有属性


三、封装的优点

优点说明
数据保护 防止外部代码意外修改关键数据(如银行账户余额)。
降低耦合 隐藏实现细节,修改内部逻辑不影响外部调用。
易于维护 代码模块化,错误更容易定位。
灵活性 可在 getter/setter 中添加额外逻辑(如日志、校验)。

四、封装的常见应用场景

(1) 数据验证

class User:
def __init__(self, username):
self.username = username # 通过 setter 校验

@property
def username(self):
return self.__username

@username.setter
def username(self, value):
if not value.isalnum():
raise ValueError("用户名只能包含字母和数字")
self.__username = value

user = User("Alice123")
user.username = "Bob!" # 触发 ValueError

(2) 只读属性

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

@property
def radius(self): # 只读 getter
return self.__radius

@property
def area(self): # 动态计算属性
return 3.14 * self.__radius 2

c = Circle(5)
print(c.area) # 78.5
# c.radius = 10 # 报错!无 setter

(3) 延迟加载(Lazy Loading)

class Database:
def __init__(self):
self.__connection = None

@property
def connection(self):
if self.__connection is None:
self.__connection = self.__connect()
return self.__connection

def __connect(self):
print("建立数据库连接…")
return "Connection Object"

db = Database()
print(db.connection) # 第一次调用时初始化连接


五、注意事项

  • Python 没有真正的私有成员:
    • 双下划线 __ 仅触发名称修饰(如 __attr 变为 _ClassName__attr),仍可强制访问,但约定禁止这样做。
  • 避免过度封装:
    • 简单数据类(如 DTO)可能不需要 getter/setter。
  • 优先使用 @property:
    • 比 Java 风格的 get_xxx()/set_xxx() 更 Pythonic。

  • 六、封装 vs 非封装对比

    非封装示例(风险高)

    class BankAccount:
    def __init__(self, balance):
    self.balance = balance # 直接暴露属性

    account = BankAccount(1000)
    account.balance = 500 # 非法操作,但无法阻止

    封装示例(安全)

    class BankAccount:
    def __init__(self, balance):
    self.__balance = balance

    def deposit(self, amount):
    if amount > 0:
    self.__balance += amount

    def withdraw(self, amount):
    if 0 < amount <= self.__balance:
    self.__balance -= amount

    def get_balance(self):
    return self.__balance

    account = BankAccount(1000)
    account.withdraw(500) # 必须通过方法操作
    # account.__balance = -1000 # 无法直接修改


    全文总结

    封装是面向对象的核心原则,旨在隐藏实现细节、保护数据并简化使用。Python 通过单下划线“_”和双下划线“__”实现受保护与私有成员的命名约定,配合名称修饰机制防止直接访问;@property 装饰器将方法伪装成属性,在保持接口一致的同时加入校验、日志等逻辑;也可通过专门的公有方法强制所有操作都走统一入口。封装带来数据安全、低耦合、易维护与灵活性,常用于数据验证、只读属性、延迟加载等场景。但 Python 没有绝对私有,仍需开发者自律;简单数据类不宜过度封装。合理使用封装,可构建健壮、易维护的代码。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 编程与数学 02-017 Python 面向对象编程 05课题、封装
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!