国庆节10月1日
--


封装的含义、类属性与实例属性、私有属性与私有方法的定义(__ 前缀)以及 Python 的"伪私有"机制

封装就是把数据(属性)和操作数据的函数(方法)捆绑在一起,形成一个独立的单元(类),并隐藏内部的实现细节,只对外暴露必要的功能(方法)。
一句话:该让别人看的露出来,不该看的藏起来。
1class Car:2 # 类属性:所有实例对象共享的3 wheel = 4 # 轮胎数量4 tax_rate = 0.1 # 购置税税率5
6 def __init__(self, c_color, c_brand, c_name):7 # 实例属性:每个对象各自一份8 self.color = c_color9 self.brand = c_brand10 self.name = c_name11
12 def start(self):13 print(f'{self.brand} {self.name} 正在启动...')14
15 def stop(self):16 print(f'{self.brand} {self.name} 停止行驶...')| 类型 | 写在哪 | 特点 |
|---|---|---|
| 类属性 | 类体里、方法外 | 所有实例共享(如 wheel = 4) |
| 实例属性 | __init__ 里用 self.xxx | 每个对象各有一份(如 self.color) |
1class Car:2 def __init__(self, c_color, c_brand, c_name, c_owner):3 self.color = c_color4 self.brand = c_brand5 self.name = c_name6 self.__owner = c_owner # 私有属性:名字前加 __7
8 def start(self):9 print(f'{self.brand} {self.name} 正在启动...')10
11 def run(self):12 print(f'{self.__owner} : {self.brand} {self.name} 正在行驶...')13 self.__control_fuel() # 类的内部可以调用私有方法14
15 def __control_fuel(self): # 私有方法:名字前加 __16 print(f'{self.brand} {self.name} 正在控制燃油分配...')17
18 def get_owner(self): # 对外暴露一个"脱敏"的读取方式19 return self.__owner[0:1] + "**"| 公共属性/方法 | 私有属性/方法 | |
|---|---|---|
| 定义方式 | 直接写名字 | 名字前加 两个下划线 __ |
| 类的内部 | 可以访问 | 可以访问 |
| 类的外部 | 可以访问 | 不能访问 |
| 应用场景 | 对外功能 | 不想对使用者公开的内部实现 |
Python 中并没有真正的私有机制,只是”约定”:名字前加 __ 的属性会被改名成 _类名__属性名,所以在外面写 car._Car__owner 依然能访问到——但不要这么干,那等于绕过约定。
私有属性不是”藏起来就完事”,而是要提供安全的对外接口。比如例子里的 get_owner() 返回脱敏后的名字(涛哥 → 涛**),既满足了外部需求,又不泄露完整信息。
__init__ 方法里)__;它们只能在类的内部使用_类名__属性名get_owner()) 2-1 写一个带私有属性的类
定义 BankAccount 类:私有属性 __balance(余额),提供 deposit(金额) 存钱、get_balance() 查余额两个公共方法。
一级 · 思路:余额设为私有,只通过方法修改和读取
二级 · 方法:self.__balance 在 __init__ 里初始化
三级 · 骨架:def deposit(self, amount): self.__balance += amount
1# 2-12class BankAccount:3 def __init__(self, card, balance):4 self.__card = card # 私有:卡号5 self.__balance = balance # 私有:余额6
7 def deposit(self, amount):8 if amount <= 0:9 print("存款金额必须大于 0")10 return11 self.__balance += amount12 print(f"存款成功,当前余额:{self.__balance}")13
14 def get_balance(self):15 return self.__balance16
17
18account = BankAccount("6222021234567890", 100)19account.deposit(50)20print(account.get_balance()) # 150 2-2 验证”私有”并不真私有
在类外面分别尝试访问 __balance 和 _类名__balance,观察两者的结果并解释原因。
一级 · 思路:直接用点号访问私有属性会报错,但加上类名前缀就”绕”过去了
二级 · 方法:account.__balance(报 AttributeError)/ account._BankAccount__balance
三级 · 骨架:用 try/except 捕获 AttributeError 打印提示
1# 2-2:私有并不真私有2try:3 print(account.__balance)4except AttributeError as e:5 print("直接访问私有属性失败:", e) # 报错6print(account._BankAccount__balance) # 150(能"绕"进去,但不建议这么做) 2-3 提供脱敏接口
给 BankAccount 加一个方法,返回脱敏后的账户信息(比如卡号只留后 4 位)。
一级 · 思路:私有属性做到”内部完整、对外脱敏”
二级 · 方法:字符串切片 card[-4:]
三级 · 骨架:return "****" + self.__card[-4:]
1# 2-32class BankAccount:3 def __init__(self, card, balance):4 self.__card = card # 私有:卡号5 self.__balance = balance # 私有:余额6
7 def deposit(self, amount):8 if amount <= 0:9 print("存款金额必须大于 0")10 return11 self.__balance += amount12 print(f"存款成功,当前余额:{self.__balance}")13
14 def get_balance(self):15 return self.__balance16
17 def get_card_info(self): # 脱敏接口18 return "****" + self.__card[-4:]19
20
21account = BankAccount("6222021234567890", 100)22print(account.get_card_info()) # ****7890如果你喜欢,那么欢迎来到我的世界!
了解更多暂未播放



"生活不是等待暴风雨过去,而是学会在雨中跳舞。"—— 塞维涅夫人


