class BankAccount:
def __init__(self, account_holder, initial_balance=0):
"""
初始化银行账户
:param account_holder: 账户持有人姓名
:param initial_balance: 初始余额,默认为0
"""
self.account_holder = account_holder
self.balance = initial_balance
self.transactions = [] # 记录交易历史
def deposit(self, amount):
"""
存款操作
:param amount: 存款金额
"""
if amount <= 0:
print("存款金额必须大于0")
return
self.balance += amount
self.transactions.append(f"存款: +{amount:.2f}")
print(f"成功存款 {amount:.2f}。当前余额: {self.balance:.2f}")
def withdraw(self, amount):
"""
取款操作
:param amount: 取款金额
"""
if amount <= 0:
print("取款金额必须大于0")
return
if amount > self.balance:
print("余额不足,无法完成取款")
return
self.balance -= amount
self.transactions.append(f"取款: -{amount:.2f}")
print(f"成功取款 {amount:.2f}。当前余额: {self.balance:.2f}")
def get_balance(self):
"""
获取当前余额
"""
return self.balance
def get_transaction_history(self):
"""
获取交易历史记录
"""
return self.transactions
def __str__(self):
return f"账户持有人: {self.account_holder}, 当前余额: {self.balance:.2f}"
if __name__ == "__main__":
name = input("请输入账户持有人姓名: ")
while True:
try:
initial_deposit = float(input("请输入初始存款金额: "))
if initial_deposit < 0:
print("初始存款金额不能为负数,请重新输入")
continue
break
except ValueError:
print("请输入有效的数字")
# 创建账户
account = BankAccount(name, initial_deposit)
print(f"\n账户创建成功!")
print(account)
# 循环操作
while True:
print("\n请选择操作:")
print("1. 存款")
print("2. 取款")
print("3. 查询余额")
print("4. 查看交易记录")
print("5. 退出")
choice = input("请输入选项(1-5): ")
if choice == "1":
# 存款
while True:
try:
amount = float(input("请输入存款金额: "))
if amount <= 0:
print("存款金额必须大于0")
continue
account.deposit(amount)
break
except ValueError:
print("请输入有效的数字")
elif choice == "2":
# 取款
while True:
try:
amount = float(input("请输入取款金额: "))
if amount <= 0:
print("取款金额必须大于0")
continue
account.withdraw(amount)
break
except ValueError:
print("请输入有效的数字")
elif choice == "3":
# 查询余额
print(f"\n当前余额: {account.get_balance():.2f}")
elif choice == "4":
# 查看交易记录
print("\n交易记录:")
for transaction in account.get_transaction_history():
print(transaction)
if not account.get_transaction_history():
print("暂无交易记录")
elif choice == "5":
# 退出
print("感谢使用银行账户系统,再见!")
break
else:
print("无效的选项,请重新输入")
类结构:
BankAccount
封装了银行账户的所有功能主要组件:
class BankAccount:
# 1. 初始化方法
def __init__(self, account_holder, initial_balance=0)
# 2. 存款功能
def deposit(self, amount)
# 3. 取款功能
def withdraw(self, amount)
# 4. 查询功能
def get_balance(self)
def get_transaction_history(self)
# 5. 字符串表示
def __str__(self)
用户交互:
if __name__ == "__main__":
实现交互式命令行界面数据建模:
功能实现原则:
交互流程:
开始 → 输入账户信息 → 主菜单 → 选择操作 → 执行功能 → 返回主菜单 → 退出
异常处理:
状态管理:
balance
变量实时跟踪账户余额transactions
列表完整记录所有交易历史用户友好性:
扩展性考虑:
- 用户输入姓名和初始金额
- 系统创建账户对象
- 用户选择存款:
- 输入存款金额
- 系统验证并执行存款
- 更新余额和交易记录
- 用户选择查询:
- 系统显示当前余额
- 用户退出系统
该代码定义了一个BankAccount
类来模拟银行账户的基本操作,包括初始化账户、存款、取款、查询余额、查看交易记录等功能。在if __name__ == "__main__"
模块中,实现了与用户的交互,让用户能够创建账户并进行各种操作。
__init__
方法account_holder
(账户持有人姓名)和initial_balance
(初始余额,默认为0)两个参数。self.account_holder
(存储账户持有人姓名)、self.balance
(存储账户余额)、self.transactions
(存储交易历史记录的空列表)。deposit
方法amount
是否小于等于0,若为真,打印提示信息并返回,不进行存款操作。self.balance
上,并将存款交易记录(格式为"存款: +{amount:.2f}"
)添加到self.transactions
列表中,同时打印存款成功信息和当前余额。withdraw
方法amount
是否小于等于0,若是,打印提示信息并返回。self.balance
,若大于,打印余额不足提示信息并返回。"取款: -{amount:.2f}"
)添加到self.transactions
列表中,同时打印取款成功信息和当前余额。get_balance
方法self.balance
。get_transaction_history
方法self.transactions
列表。__str__
方法print()
函数打印账户对象时,会自动调用该方法,返回一个包含账户持有人姓名和当前余额的字符串(格式为"账户持有人: {self.account_holder}, 当前余额: {self.balance:.2f}"
)。if __name__ == "__main__"
模块分析input()
函数获取用户输入的账户持有人姓名name
。try-except
块,确保用户输入的初始存款金额initial_deposit
是有效的数字且不为负数,然后创建BankAccount
对象account
。__str__
方法)。choice
,执行相应的操作(调用BankAccount
类的对应方法)。try-except
块确保用户输入的金额是有效的数字,并进行相应的业务逻辑处理(调用类方法)。5
),打印感谢信息并终止循环,结束程序。BankAccount
类中,体现了良好的面向对象设计思想,使代码结构清晰,便于维护和扩展。__init__
和__str__
是两个特殊的魔法方法__init__
方法class BankAccount:
def __init__(self, account_holder, initial_balance=0):
self.account_holder = account_holder # 设置账户持有人
self.balance = initial_balance # 设置初始余额
self.transactions = [] # 初始化交易记录
self
(指向新创建的对象)account = BankAccount("张三", 1000) # 自动调用__init__
None
)__str__
方法print()
或str()
时自动调用def __str__(self):
return f"账户持有人: {self.account_holder}, 当前余额: {self.balance:.2f}"
account = BankAccount("李四", 500)
print(account) # 自动调用__str__,输出:账户持有人: 李四, 当前余额: 500.00
__str__
,Python会使用__repr__
作为备用特性 | __init__ |
__str__ |
---|---|---|
调用时机 | 创建实例时 | 调用print() 或str() 时 |
主要用途 | 初始化对象属性 | 定义对象的可读字符串表示 |
返回值 | 不应返回任何值 | 必须返回字符串 |
是否必需 | 非必需(但绝大多数类都会实现) | 非必需(但建议重要类都实现) |
示例调用场景 | obj = ClassName(args) |
print(obj) 或 str(obj) |
在银行账户系统中,这两个方法协同工作:
# 创建账户(调用__init__)
account = BankAccount("王五", 2000)
# 查看账户信息(调用__str__)
print(account)
# 输出:账户持有人: 王五, 当前余额: 2000.00
__init__
: 确保对象创建后即处于有效状态,避免后续出现属性未定义的错误
__str__
: 提供比默认内存地址(如<__main__.BankAccount object at 0x...>
)更有意义的输出
类似方法__repr__
:用于开发者调试,应返回明确的创建表达式
def __repr__(self):
return f'BankAccount("{self.account_holder}", {self.balance})'
在银行账户系统中,良好的__str__
实现可以帮助:
__str__
方法的语言规范__str__
方法必须返回一个字符串对象(str
类型)。当调用print(obj)
或str(obj)
时,解释器会自动执行这个方法并显示其返回值。print()
的协作机制print(account) # 内部实际执行:
# 1. 调用account.__str__()
# 2. 打印该方法返回的字符串
def __str__(self):
return f"账户持有人: {self.account_holder}, 当前余额: {self.balance:.2f}"
返回值内容: 返回一个格式化的字符串,包含账户持有人和带两位小数的余额 (例如:"账户持有人: 张三, 当前余额: 1000.00"
)
技术细节:
f"..."
:f-string格式化字符串(Python 3.6+):.2f
:将浮点数格式化为2位小数
❌ 错误示例:
def __str__(self):
print("账户信息...") # 错误!__str__不应该直接打印
print(account)
会导致: TypeError: __str__ returned non-string (type NoneType)
✅ 正确做法: 必须通过return
返回字符串,让调用者决定如何处理这个字符串。
这种设计体现了关注点分离原则:
__str__
的职责: 只负责生成对象的字符串表示形式 (不关心这个字符串是用来打印、记录日志还是其他用途)
调用方的自由: 返回字符串后,调用者可以:
# 选择1:直接打印
print(account)
# 选择2:存入文件
with open("log.txt", "a") as f:
f.write(str(account))
# 选择3:拼接其他字符串
msg = "账户状态:" + str(account)
语言 | 类似机制 |
---|---|
Java | toString() 方法 |
C# | ToString() 方法 |
JavaScript | toString() 原型方法 |
C++ | 重载 << 操作符 |
while True
语句、 if elif else
语句和 try except
语句的详细介绍while True
语句True
始终满足(实际上就是一直满足),循环体就会不断执行。通常需要在循环内部通过 break
语句来终止循环。while True:
# 循环体代码
if 终止条件:
break
while True:
user_input = input("请输入一个数字(输入 'q' 退出): ")
if user_input == 'q':
break
try:
num = int(user_input)
print(f"你输入的数字是: {num}")
except ValueError:
print("输入无效,请输入一个整数。")
if elif else
语句if
后面可以跟多个 elif
(表示“否则如果”),最后可以有一个可选的 else
(表示前面条件都不满足时执行)。if 条件1:
# 条件1满足时执行的代码
elif 条件2:
# 条件2满足时执行的代码
else:
# 前面条件都不满足时执行的代码
score = 85
if score >= 90:
print("优秀")
elif score >= 80:
print("良好")
elif score >= 60:
print("及格")
else:
print("不及格")
try except
语句try
块中放置可能引发异常的代码,except
块用于处理捕获到的异常。try:
# 可能引发异常的代码
except 异常类型:
# 处理异常的代码
try:
result = 10 / 0 # 会引发 ZeroDivisionError 异常
except ZeroDivisionError:
print("除数不能为零!")
FileNotFoundError
、网络连接超时等)。在实际编程中,这三种语句经常结合使用。例如在银行账户系统代码里:
while True:
try:
initial_deposit = float(input("请输入初始存款金额: "))
if initial_deposit < 0:
print("初始存款金额不能为负数,请重新输入")
continue
break
except ValueError:
print("请输入有效的数字")
这里
while True
创建了一个循环让用户不断输入,直到输入有效(通过break
终止循环)。try except
用于处理用户输入不是数字的情况(捕获ValueError
异常),if
语句用于进一步校验输入数字的合理性(是否为负数)。
再比如在取款操作的代码中:
elif choice == "2":
# 取款
while True:
try:
amount = float(input("请输入取款金额: "))
if amount <= 0:
print("取款金额必须大于0")
continue
account.withdraw(amount)
break
except ValueError:
print("请输入有效的数字")
break
和 continue
是用于控制循环流程的关键字break
for
循环或 while
循环),循环体中 break
语句之后的代码将不再执行,程序会跳出循环,继续执行循环后面的代码。for i in range(10):
if i == 5:
break
print(i)
# 输出结果为 0 1 2 3 4,当 i 等于 5 时,循环终止
continue
continue
语句之后的代码,直接进入下一次循环的条件判断(对于 for
循环,会继续迭代下一个元素;对于 while
循环,会继续判断循环条件)。for i in range(10):
if i % 2 == 0:
continue
print(i)
# 输出结果为 1 3 5 7 9,当 i 是偶数时,跳过本次循环的打印操作,直接进入下一次循环
break
break
来提前结束循环。例如在一个列表查找元素的循环中,一旦找到目标元素,就可以用 break
停止继续查找。my_list = [10, 20, 30, 40, 50]
target = 30
for num in my_list:
if num == target:
print(f"找到目标元素 {target}")
break
continue
continue
。比如在遍历一个数字列表时,想忽略其中的偶数,只对奇数进行某些计算或处理。numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for num in numbers:
if num % 2 == 0:
continue # 跳过偶数
# 以下是对奇数的处理逻辑
print(f"处理奇数: {num}")
break
:在循环嵌套的情况下,break
只会终止它所在的那一层循环。
for i in range(5):
for j in range(5):
if j == 2:
break # 只会跳出内层的 j 循环
print(f"i={i}, j={j}")
# 输出结果是 当 j 等于 2 时,内层循环停止,外层循环继续
continue
:同样在循环嵌套中,continue
也只影响它所在的那一层循环,会跳过该层循环中 continue
后面的代码,进入该层循环的下一次迭代。
for i in range(5):
for j in range(5):
if j == 2:
continue # 跳过内层 j 循环中 j=2 时后续的代码,继续 j 的下一次循环
print(f"i={i}, j={j}")
# 输出结果是 当 j 等于 2 时,跳过本次 j 循环的打印操作,j 继续递增
总的来说,break
用于快速结束循环,continue
用于有条件地跳过循环体中的部分代码,它们为程序员提供了灵活控制循环流程的手段。