封装与属性
项目:构建一个“银行账户系统”,展示封装、私有属性以及使用Python的@property装饰器。
01. 学习目标
在本课结束时,您将能够:
- 理解封装及其在面向对象编程中的重要性
- 使用私有属性(
_和__)来隐藏内部数据 - 通过获取器/设置器方法访问私有变量
- 使用
@property装饰器简化代码 - 为安全、不可变的数据创建只读属性
02. 问题场景
您正在构建一个银行账户系统,其中每个用户的余额必须是私有和受保护的。
用户不应直接修改余额 — 只能通过验证输入的受控方法进行修改。
封装确保敏感数据免受滥用。
03. 第一步 – 封装基础
封装隐藏了对象的内部细节,仅暴露必要的接口。
在Python中,以 _ 或 __ 开头的属性被视为 根据约定的私有属性。
class Person:
def __init__(self, name, age):
self.name = name # 公有属性
self.__age = age # 私有属性
def get_age(self):
return self.__age # 通过方法访问
p = Person("Sabin", 30)
print(p.name) # Sabin
# print(p.__age) # ❌ AttributeError
print(p.get_age()) # 30
04. 第2步 – 获取器和设置器方法
使用获取器和设置器方法安全地访问和修改私有属性。
class Account:
def __init__(self, balance):
self.__balance = balance
def get_balance(self):
return self.__balance
def set_balance(self, amount):
if amount >= 0:
self.__balance = amount
else:
print("无效的余额")
acc = Account(100)
print(acc.get_balance()) # 100
acc.set_balance(200)
print(acc.get_balance()) # 200
05. 第3步 – 使用 @property
Python 的 @property 装饰器允许你创建 getter/setter 功能
同时将属性访问视为公共属性。
class Account:
def __init__(self, balance):
self.__balance = balance
@property
def balance(self): # Getter
return self.__balance
@balance.setter
def balance(self, amount): # 设置器
if amount >= 0:
self.__balance = amount
else:
print("无效的余额")
acc = Account(100)
print(acc.balance) # 100
acc.balance = 300
print(acc.balance) # 300
现在您可以自然地访问和修改 balance,而不会破坏封装性。
06. 第四步 – 只读属性
仅定义一个 getter(没有 setter)以使属性变为只读。
class Circle:
def __init__(self, r):
self.__r = r
@property
def area(self):
return 3.14 * self.__r * self.__r
c = Circle(5)
print(c.area) # 78.5
# c.area = 100 # ❌ AttributeError: can't set attribute
07. 第5步 – 实践示例
示例 1:温度验证
class Temperature:
def __init__(self, celsius):
self.__celsius = celsius
@property
def celsius(self):
return self.__celsius
@celsius.setter
def celsius(self, value):
if value >= -273: # 绝对零度检查
self.__celsius = value
else:
print("无效的温度")
t = Temperature(25)
print(t.celsius) # 25
t.celsius = -300 # 无效的温度
示例 2:具有只读成绩的学生
class Student:
def __init__(self, name, grade):
self.name = name
self.__grade = grade
@property
def grade(self): # 只读属性 return self.__grade s = Student("Anna", "A") print(s.name, s.grade) # Anna A # s.grade = "B" # ❌ AttributeError: 无法设置属性
08. 小项目 – 安全银行账户
使用封装和属性构建一个简单的银行账户系统。
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.__balance = balance
@property
def balance(self):
return self.__balance
@balance.setter
def balance(self, amount):
if amount >= 0:
self.__balance = amount
else:
print("无效金额 — 余额不能为负数。")
def deposit(self, amount):
if amount > 0:
self.__balance += amount
print(f"存款 {amount}. 新余额: {self.__balance}")
else:
print("存款必须为正数。")
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
print(f"已提取 {amount}. 新余额: {self.__balance}")
else:
print("无效的提取金额。")
acc = BankAccount("Sabin", 1000)
acc.deposit(500)
acc.withdraw(200)
print("最终余额:", acc.balance)
输出:
存入500。新余额:1500
取出200。新余额:1300
最终余额:1300
09. 反射
你已经学习了如何:
- 使用封装来保护数据完整性
- 应用getter/setter 方法进行受控访问
- 通过
@property装饰器简化代码 - 为不可变数据创建只读属性
- 在现实世界系统中应用这些概念(如银行系统)

