文件处理part3、函数的基本使用-练习
1、编写文件修改功能,调用函数时,传入三个参数(修改的文件路径,要修改的内容,修改后的内容)既可完成文件的修改
def file_updating(file_path, source_content, new_content):
import os
if not os.path.isfile(file_path):
print('文件不存在')
return
# 修改文件方式一(1):
"""
with open(rf'{file_path}', mode='rt', encoding='utf-8') as f:
data = f.read()
with open(rf'{file_path}', mode='wt', encoding='utf-8') as f:
f.write(data.replace(source_content, new_content))
"""
# 修改文件方式一(2):
"""
li = []
with open(rf'{file_path}', mode='rt', encoding='utf-8') as f:
for line in f:
line = line.replace(source_content, new_content)
li.append(line)
with open(rf'{file_path}', mode='wt', encoding='utf-8') as f:
for line in li:
f.write(line)
"""
# 修改文件方式二:(推荐)
with open(rf'{file_path}', mode='rt', encoding='utf-8') as f1, \
open('swap.txt', mode='wt', encoding='utf-8') as f2:
for line in f1:
line = line.replace(source_content, new_content)
f2.write(line)
os.remove(rf'{file_path}')
os.rename('swap.txt', rf'{file_path}')
print("文件修改完成".center(50, '-'))
# file_updating('a.txt', 'alex_dsb', 'alex')
# file_updating('a.txt', 'alex', 'alex_dsb')
2、编写tail工具
# supplemental_logs功能写到另一个文件中, 实现自动自己追加日志内容
def supplemental_logs(log_path):
"""追加日志内容。"""
import datetime
with open(rf'{log_path}', mode='at', encoding='utf-8') as f:
f.write(f'日志:{datetime.datetime.now()}'.center(50, '-') + '\n')
# supplemental_logs('access.log')
def test_log(log_path, encoding_type='utf-8', time_interval=0.3):
"""检测日志新增的内容,并打印显示到屏幕上"""
with open(f'{log_path}', mode='rb') as f:
f.seek(0, 2)
while True:
res = f.readline()
# 优化: 有内容res的隐式布尔为True, 没有内容(b'')为False
# if len(res):
if res:
print(res.decode(encoding_type), end='')
else:
import time
time.sleep(time_interval)
# test_log('access.log')
3、编写登录功能
def login():
"""
登录功能
:return: 当用户登录成功时,把用户名当作返回值
"""
import os
if not os.path.isfile(DB_PATH):
print('用户账户文件不存在,请先注册!')
return
name = input("your name>>:").strip()
if name in login_state:
print(f'欢迎【{name}】再次登录!')
return
pwd = input("your pwd>>:").strip()
with open(DB_PATH, mode='rt', encoding='utf-8') as f:
for line in f:
res = line.strip()
if not res:
continue
username, password, _ = res.split(':')
if username == name and password == pwd:
print('登录成功!')
login_state.append(username)
return username
else:
print('登录失败!账号或密码错误!')
4、编写注册功能
def register():
name = input("your name>>:").strip()
if not name:
print("用户名不能为空!")
return
with open(DB_PATH, mode='a+', encoding='utf-8') as f:
f.seek(0, 0)
for line in f:
res = line.strip()
if not res:
continue
if res.split(':')[0] == name:
print('该用户已经存在!')
break
else:
f.seek(0, 2)
pwd = input("your pwd>>:").strip()
if not pwd:
print('密码输入不能为空!')
return
f.write(f'{name}:{pwd}:{0}\n')
print(f'恭喜【{name}】!注册成功!'.center(50, '-'))
5、编写用户认证功能
login_state = []
DB_PATH = r'db.txt'
def login():
"""
登录功能
:return: 当用户登录成功时,把用户名当作返回值
"""
import os
if not os.path.isfile(DB_PATH):
print('用户账户文件不存在,请先注册!')
return
name = input("your name>>:").strip()
if name in login_state:
print(f'欢迎【{name}】再次登录!')
return
pwd = input("your pwd>>:").strip()
with open(DB_PATH, mode='rt', encoding='utf-8') as f:
for line in f:
res = line.strip()
if not res:
continue
username, password, _ = res.split(':')
if username == name and password == pwd:
print('登录成功!')
login_state.append(username)
return username
else:
print('登录失败!账号或密码错误!')
# 4、编写注册功能
def register():
name = input("your name>>:").strip()
if not name:
print("用户名不能为空!")
return
with open(DB_PATH, mode='a+', encoding='utf-8') as f:
f.seek(0, 0)
for line in f:
res = line.strip()
if not res:
continue
if res.split(':')[0] == name:
print('该用户已经存在!')
break
else:
f.seek(0, 2)
pwd = input("your pwd>>:").strip()
if not pwd:
print('密码输入不能为空!')
return
f.write(f'{name}:{pwd}:{0}\n')
print(f'恭喜【{name}】!注册成功!'.center(50, '-'))
# 5、编写用户认证功能
dic = {'1': login, '0': register}
def authentication():
"""
认证功能
:return: 只有用户登录成功才会返回用户名,才会True,再把用户名返回
"""
while True:
print('''
0 注册
1 登录
''')
cmd = input("根据数字选择相应的功能>>:").strip()
if not cmd:
print("命令不能为空!")
continue
if cmd not in dic:
print("数字范围超出!")
continue
res = dic[cmd]()
if res:
return res
# authentication()
6、选做题:编写ATM程序
# 数据来源于文件db.txt
# 用户登录成功后,内存中记录下该状态,上述功能以当前登录状态为准,必须先登录才能操作
# 1、充值功能:用户输入充值钱数,db.txt中该账号钱数完成修改
# 2、转账功能:用户A向用户B转账1000元,db.txt中完成用户A账号减钱,用户B账号加钱
# 3、提现功能:用户输入提现金额,db.txt中该账号钱数减少
# 4、查询余额功能:输入账号查询余额
import os
def read_file(username):
"""读取文件:返回用户名,密码,金额"""
with open(DB_PATH, mode='r', encoding='utf-8') as f:
for line in f:
res = line.strip()
if not res:
continue
name, pwd, money = res.split(":")
if username == name:
return name, pwd, money
def top_up_money(*args):
"""充值"""
username = args[0]
top_up_number = input('请充值>>:').strip()
if not top_up_number.isdigit():
print('请输入数字')
return
top_up_number = int(top_up_number)
with open(DB_PATH, mode='r', encoding='utf-8') as f1, \
open('.txt.swap', mode='w', encoding='utf-8') as f2:
for line in f1:
res = line.strip()
if not res:
continue
name, pwd, money = res.split(":")
if username == name:
money = str(int(money) + top_up_number)
# money = int(money)
# money += top_up_number
# money = str(money)
f2.write(f'{name}:{pwd}:{money}\n')
else:
print('恭喜您充值完毕!'.center(50, '-'))
os.remove(DB_PATH)
os.rename('.txt.swap', DB_PATH)
def transfer(*args):
"""转账"""
username = args[0]
other_name = input('请输入你要施舍的用户>>:').strip()
username_exists = False
with open(DB_PATH, mode='r', encoding='utf-8') as f:
for line in f:
res = line.strip()
if not res:
continue
name, pwd, money = res.split(":")
if other_name == name:
username_exists = True
break
if not username_exists:
print('人都没有这个人,转个毛!')
return
transfer_number = input('说吧!你要转多少出去>>:').strip()
if not transfer_number.isdigit():
print('请输入数字')
return
# 修改文件:减自己的钱
balance_enough = False
transfer_number = int(transfer_number)
with open(DB_PATH, mode='r', encoding='utf-8') as f1, \
open('.txt.swap', mode='w', encoding='utf-8') as f2:
for line in f1:
res = line.strip()
if not res:
continue
name, pwd, money = res.split(":")
if username == name:
money = int(money)
if transfer_number > money:
print('穷鬼!自己的钱都不够,转毛线啊!')
else:
money -= transfer_number
balance_enough = True
money = str(money)
f2.write(f'{name}:{pwd}:{money}\n')
os.remove(DB_PATH)
os.rename('.txt.swap', DB_PATH)
if not balance_enough:
return
# 修改文件:加别人的钱
with open(DB_PATH, mode='r', encoding='utf-8') as f1, \
open('.txt.swap', mode='w', encoding='utf-8') as f2:
for line in f1:
res = line.strip()
if not res:
continue
name, pwd, money = res.split(":")
if other_name == name:
money = int(money)
money += transfer_number
money = str(money)
f2.write(f'{name}:{pwd}:{money}\n')
else:
print(f'恭喜您转账给【{other_name}】成功!'.center(50, '-'))
os.remove(DB_PATH)
os.rename('.txt.swap', DB_PATH)
def withdraw_deposit(*args):
"""提现."""
username = args[0]
withdraw_number = input('请提现>>:').strip()
if not withdraw_number.isdigit():
print('请输入数字')
return
withdraw_number = int(withdraw_number)
is_successful = False
with open(DB_PATH, mode='r', encoding='utf-8') as f1, \
open('.txt.swap', mode='w', encoding='utf-8') as f2:
for line in f1:
res = line.strip()
if not res:
continue
name, pwd, money = res.split(":")
if username == name:
money = int(money)
if money < withdraw_number:
print(f'对不起,你的余额不足,当前余额【{money}】元')
else:
money -= withdraw_number
is_successful = True
money = str(money)
f2.write(f'{name}:{pwd}:{money}\n')
if is_successful:
print('恭喜您提现成功!'.center(50, '-'))
os.remove(DB_PATH)
os.rename('.txt.swap', DB_PATH)
def balance_inquiry(*args):
"""查询余额"""
username = args[0]
with open(DB_PATH, mode='r', encoding='utf-8') as f:
for line in f:
res = line.strip()
if not res:
continue
name, _, money = res.split(":")
if username == name:
print(f'您当前余额为【{money}】元!')
'''
# func_dic = {'1': top_up_money, '2': transfer, '3': withdraw_deposit, '4': balance_inquiry}
# def run():
# # 这里把用户返回的用户名传入以下4个功能中,以下功能的操作都是对该用户的功能的操作。
# username = authentication()
#
# while True:
# print("""
# 1 充值
# 2 转账
# 3 提现
# 4 查询余额
# """)
# cmd = input("根据数字选择相应的功能>>:").strip()
# if cmd.lower() == 'q':
# print('再见。。。。')
# break
# if not cmd:
# print("命令不能为空!")
# continue
# if cmd not in func_dic:
# print("数字范围超出!")
# continue
# func_dic[cmd](username)
'''
# 优化:
func_dic = {
'0': ('退出', exit),
'1': ('充值', top_up_money),
'2': ('转账', transfer),
'3': ('提现', withdraw_deposit),
'4': ('查询余额', balance_inquiry),
}
def run():
# 这里把用户返回的用户名传入以下4个功能中,以下功能的操作都是对该用户的功能的操作。
username = authentication()
while True:
for key, value in func_dic.items():
print(f'({key}):{value[0]}', end=' ')
print()
cmd = input("根据数字选择相应的功能>>:").strip()
if not cmd.isdigit():
print("请输入数字")
continue
if cmd not in func_dic:
print("数字范围超出!")
continue
func_dic[cmd][1](username)
# run()
继续优化完善(最后):