本文目录导读:

我来为你详细介绍Python私有属性的封装案例,包含多种使用场景。
基础私有属性封装
class BankAccount:
def __init__(self, account_holder, initial_balance=0):
self._account_holder = account_holder # 受保护属性(约定)
self.__balance = initial_balance # 私有属性(名称修饰)
# getter方法
def get_balance(self):
return self.__balance
# setter方法
def deposit(self, amount):
if amount <= 0:
raise ValueError("存款金额必须大于0")
self.__balance += amount
def withdraw(self, amount):
if amount <= 0:
raise ValueError("取款金额必须大于0")
if amount > self.__balance:
raise ValueError("余额不足")
self.__balance -= amount
# 测试
account = BankAccount("张三", 1000)
print(account.get_balance()) # 1000
account.deposit(500)
account.withdraw(200)
print(account.get_balance()) # 1300
# 无法直接访问私有属性
# print(account.__balance) # AttributeError
# 名称修饰后的访问(不推荐)
print(account._BankAccount__balance) # 1300
使用@property装饰器
class Student:
def __init__(self, name, score):
self.__name = name
self.__score = score
@property
def name(self):
"""姓名属性,只读"""
return self.__name
@property
def score(self):
"""成绩属性,可读写"""
return self.__score
@score.setter
def score(self, value):
if not isinstance(value, (int, float)):
raise TypeError("成绩必须是数字")
if value < 0 or value > 100:
raise ValueError("成绩必须在0-100之间")
self.__score = value
@property
def grade(self):
"""计算等级,只读属性"""
if self.__score >= 90:
return 'A'
elif self.__score >= 80:
return 'B'
elif self.__score >= 70:
return 'C'
elif self.__score >= 60:
return 'D'
else:
return 'F'
# 测试
student = Student("小明", 85)
print(student.name) # 小明
print(student.score) # 85
student.score = 92 # 使用setter
print(student.score) # 92
print(student.grade) # A
# student.name = "小红" # AttributeError, name是只读的
完整封装案例:用户管理系统
from datetime import datetime
import re
class User:
def __init__(self, username, email, password):
self.__id = None
self.__username = username
self.__email = email
self.__password = self.__encrypt_password(password)
self.__created_at = datetime.now()
self.__last_login = None
self.__is_active = True
# 私有方法
def __encrypt_password(self, password):
"""加密密码(简化示例)"""
return hash(password)
def __validate_email(self, email):
"""验证邮箱格式"""
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return re.match(pattern, email) is not None
# 属性getter
@property
def id(self):
return self.__id
@property
def username(self):
return self.__username
@property
def email(self):
return self.__email
@email.setter
def email(self, new_email):
if not self.__validate_email(new_email):
raise ValueError("邮箱格式不正确")
self.__email = new_email
@property
def created_at(self):
return self.__created_at
@property
def last_login(self):
return self.__last_login
@property
def is_active(self):
return self.__is_active
# 公共方法
def login(self, password):
if not self.__is_active:
raise Exception("账户已被禁用")
if hash(password) != self.__password:
return False
self.__last_login = datetime.now()
return True
def change_password(self, old_password, new_password):
if hash(old_password) != self.__password:
raise ValueError("原密码不正确")
if len(new_password) < 8:
raise ValueError("新密码长度至少8位")
self.__password = self.__encrypt_password(new_password)
def deactivate(self):
"""停用账户"""
self.__is_active = False
def activate(self):
"""激活账户"""
self.__is_active = True
def to_dict(self):
"""转换为字典(不包含敏感信息)"""
return {
'id': self.__id,
'username': self.__username,
'email': self.__email,
'created_at': self.__created_at.isoformat(),
'last_login': self.__last_login.isoformat() if self.__last_login else None,
'is_active': self.__is_active
}
# 使用示例
user = User("john_doe", "john@example.com", "password123")
print(user.username) # john_doe
print(user.email) # john@example.com
# 修改邮箱
user.email = "new_email@example.com"
# 登录
if user.login("password123"):
print("登录成功")
print(f"最后登录时间: {user.last_login}")
# 修改密码
user.change_password("password123", "new_password_123")
# 输出用户信息(不含密码)
print(user.to_dict())
更高级的封装:数据校验和转换
class Temperature:
def __init__(self, celsius=0):
self.__celsius = celsius
@property
def celsius(self):
return self.__celsius
@celsius.setter
def celsius(self, value):
if value < -273.15:
raise ValueError("温度不能低于绝对零度")
self.__celsius = value
@property
def fahrenheit(self):
"""计算华氏温度(只读)"""
return (self.__celsius * 9/5) + 32
@fahrenheit.setter
def fahrenheit(self, value):
"""设置华氏温度"""
if value < -459.67:
raise ValueError("温度不能低于绝对零度")
self.__celsius = (value - 32) * 5/9
@property
def kelvin(self):
"""计算开尔文温度(只读)"""
return self.__celsius + 273.15
def __str__(self):
return f"{self.__celsius:.2f}°C ({self.fahrenheit:.2f}°F, {self.kelvin:.2f}K)"
# 测试
temp = Temperature(25)
print(temp) # 25.00°C (77.00°F, 298.15K)
temp.celsius = 100
print(temp.fahrenheit) # 212.0
temp.fahrenheit = 32
print(temp.celsius) # 0.0
print(temp.kelvin) # 273.15
封装的最佳实践
class Product:
def __init__(self, name, price, quantity):
# 使用单下划线表示受保护(子类可访问)
self._name = name
# 使用双下划线表示私有(子类不可直接访问)
self.__price = price
self.__quantity = quantity
self.__version = 1
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not value or not isinstance(value, str):
raise ValueError("产品名称不能为空")
self._name = value
@property
def price(self):
return self.__price
@price.setter
def price(self, value):
if value <= 0:
raise ValueError("价格必须大于0")
self.__price = value
self.__version += 1 # 更新版本号
@property
def quantity(self):
return self.__quantity
@quantity.setter
def quantity(self, value):
if value < 0:
raise ValueError("数量不能为负")
self.__quantity = value
self.__version += 1
@property
def total_value(self):
"""总价值(只读)"""
return self.__price * self.__quantity
@property
def version(self):
"""版本号(只读)"""
return self.__version
# 测试
product = Product("笔记本电脑", 5999.99, 10)
print(f"产品: {product.name}")
print(f"价格: {product.price}")
print(f"总价值: {product.total_value}")
product.price = 5499.99
product.quantity = 15
print(f"更新后总价值: {product.total_value}")
print(f"版本号: {product.version}") # 3
-
命名约定:
_single_underscore:受保护,表示应该被视为内部使用__double_underscore:私有,触发名称修饰(name mangling)
-
封装目的:
- 保护数据完整性
- 隐藏实现细节
- 提供统一的访问接口
-
使用场景:
- 敏感数据(密码、余额)
- 需要验证的数据(价格、成绩)
- 计算属性(总价、等级)
-
最佳实践:
- 优先使用
@property装饰器 - 提供清晰的getter/setter方法
- 在setter中进行数据验证
- 保持接口简单统一
- 优先使用
这些案例展示了Python中私有属性封装的各种模式,你可以根据实际需求选择合适的方式。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播