python中的数据封装
python中的数据封装
- 数据封装:数据的私有化,通过特殊方法调用。是面向对象的三大核心特性之一
- 变量:直接定义的变量属于公开的变量,可以从任何地方访问
- _ 变量 :_开头的变量为保护成员(直接.不显示,但可以直接打出,属于非法访问)
- _ _变量 : _ _ 开头的变量为私有化成员,不可被其他函数调用
- _ _ 变量_ _ :python中定义的特殊方法/属性(不要自定义这样的名称)
- 内置函数:
_ _ dir _ _ ():可以展示这个对象的所有属性和方法储存的名称,之后通过调用储存的名称可以实现对私有化成员的访问
_ _ init _ _ ():构造方法,在创建对象时调用
_ _ new _ _ ():实际创建实例的方法,在 _ _ init_ ()之前调用(用于不可变数据类型)
_ _ len _ _ ():相当于len()方法
_ _ getitem _ _ ():索引访问
_ _ str _ _ ():定义 str(obj) 或 print(obj) 时的输出
_ _ dict _ _ ():存储对象的属性和值的字典
_ _ repr _ _ ():定义 repr(obj) 或交互式环境直接输入 obj 时的输出
_ _ add _ _ () :+
_ _ eq _ _ ():==
_ _ lt _():<
_ _ gt _ _ ():>
- 对封装的数据的访问
通过定义实例方法进行正确的访问一些私有化的属性,也可在方法中增加一些限制条件。
class BankAccount:# 银行账户类,演示数据封装def __init__(self, account_holder, initial_balance=0):self.account_holder = account_holder # 公开的数据self._balance = initial_balance # 受保护的数据self.__transaction_history = [] # 私有化的数据@property # 将方法转化为属性进行使用def balance(self):# 获取当前余额(只读)return self._balance@balance.setter # balance的数据验证def balance(self, value):if not isinstance(value, (int, float)): # 检查balance的类型是否为int或者floatraise ValueError("余额必须是数字")if value < 0:raise ValueError("余额不能为负")self._balance = round(value, 2) # 保留两位小数def deposit(self, amount):# 存款if amount <= 0:raise ValueError("存款金额必须为正数")self._balance += amount self.__record_transaction(f"存款: +{amount:.2f}")return self._balancedef withdraw(self, amount):# 取款if amount <= 0:raise ValueError("取款金额必须为正数")if amount > self._balance:raise ValueError("余额不足")self._balance -= amountself.__record_transaction(f"取款: -{amount:.2f}")return self._balancedef __record_transaction(self, message):# 记录交易(私有方法)self.__transaction_history.append(f"{message} | 余额: {self._balance:.2f}")def get_statement(self):# 获取交易记录return "\n".join(self.__transaction_history)
# 使用示例
account = BankAccount("张三", 1000)
account.deposit(500)
account.withdraw(200)
print(f"当前余额: {account.balance}")
print("交易记录:")
print(account.get_statement())
print(account._balance) # 直接.不显示,但可以直接打出,属于非法访问
print(account.__transaction_history)# 报错,year被私有化,储存方式发生改变,因此访问不到
print(account.__dir__()) # 展示私有化成员的储存名称和方式
注:当变量私有化后,不可被直接调用,需要通过定义的方法进行调用,在
Python中可以将方法转化为属性从而实现对私有化变量的调用
- 封装过程中需要注意的事项:
- 最小化公开接口:只暴露必要的属性和方法
- 使用属性替代直接访问:通过@property控制属性访问
- 遵循命名约定:使用单下划线和双下划线表示访问级别
- 添加文档字符串:说明类的用途和用法
- 验证输入数据:在setter方法中进行数据验证(@变量.setter修饰器修饰的方法)
- 考虑使用描述符:对于需要复杂访问控制的属性