Python注册登录系统 | 控制台
前言
一、项目需求;
①
1、实现一个基于命令行的用户注册功能。
2、用户注册时必须要输入 用户名、密码、手机号码,用针对用户的输入必须进行验证。
3、用户名的规则:只能是大小写字母或数字,且不能以数字开头,长度为5~12位。
4、密码的规则:密码必须且只能由大小写和数字组成,长度为6~15位。
5、手机号码的规则:按照标准的中国手机号码规则进行校验。
6、如果校验成功,则允许用户注册,注册信息保存于数据库中。
②
1、绘制菜单,用户可以自行决定下一步做什么:登录、注册、改密、改电话、退出。
2、支持多用户注册,注册时,如果已经存在的用户名不能注册。
3、密码输入失败3次,则不再允许当前用户登录,退回到主菜单。
4、用户登录成功以后,可以修改密码和电话号码,同样需要进行正确性校验。
5、用户在输入用户名、密码或电话时,如果输错超过3次,则结束运行。
(1)利用MySQL数据库等完成注册、登录、修改密码等操作。
(2)记录用户操作的历史记录(登录、注册、改密、改电话)。
python控制台模拟系统,登录注册修改用户信息等功能
一、主页菜单(main.py)
实现思路:
简单的给控制台页面模拟出来,设置调用菜单的函数,方便后面代码执行后返回主菜单
里面主要用数字去直接做调用其他文件关键函数而已,没什么思路,那个if else判断
细节就不在外面提了,全写在代码里,和生活中及人情世故
统统注释起来
##本菜单引用其他文件函数 *safe14包里面的.mysql_system包以.取下一级,import调用多个文件
from safe14.mysql_system import regist, login,storage
#select函数
def select():
print('*' * 46)##第一排46个星星
print('*' * 7, 'Welcome To Woniuxy Info System', '*' * 7)
print('*' * 2, '注册-0', '*' , '登录-1', '*', '改密-2','*','改电话-3','*','返回-9','*' * 2)
print('*' * 46)
##以此类推46、7、2、46各行星星数其他的是绘制菜单的字符串
##定个变量flag将input里的值保存到flag里,是用户输入的,并给用户提示后面跟上
flag = input('please input menu number:')
##if判断0就去调用注册的函数进行注册,否则1、2、3、9一次类推
##否则用户输入其他数字,输入哪个去哪个
if flag=='0':
regist.regist()#注册
elif flag=='1':#登录
login.loginfo()
elif flag=='2':#改密码
login.login1()
elif flag=='3':#改电话
login.login2()
elif flag=='9':
exit('bye~')
##胡乱输入就给直接退出程序
else:
storage.stor("system.log", "输入不符合规则,退出程序")
exit('input error~')
if __name__ == '__main__':
select()
菜单页面展示👇
二、正则校验(check.py)
实现思路:
为了将代码提现的更加模块化,将所有正则校验放到单独一个文件里。
以方便其他注册用户、及修改用户信息校验直接调用此文件。干净易懂,方便以开发团队的思路去写代码。
里面主要有三大校验:用户名、密码、手机号(ASCII)校验。
下方有校验需求注释👇
'''
用户名的规则:只能是大小写字母或数字,且不能以数字开头,长度为5~12位
'''
import re##引用内置正则表达式模块
import main##引用主菜单页面模块
def check_user(username):#定义个函数,备用个参数username
pattern="^[a-zA-Z][0-9a-zA-Z]{4,11}$"
##上面定义正则规则,下面正则固定写法re.match,规则在先字符串在后,储存在res变量中,全拼result;结果
res=re.match(pattern=pattern,string=username)
if res:#这里if判断如果值出来个给返回True反之False
return True
else:
# print("用户名只能是大小写字母或数字,且不能以数字开头,长度为5~12位")
return False
#re.match:匹配成功返回一个match对象:<re.Match object; span=(0, 5), match='lency'>
'''
密码的规则:密码必须且只能由大小写字母和数字组成,长度为6~15位
print(ord(st)) #a-97 z-122 A-65 Z=90 0-48 9-57 将字符转换成ASCII
print(chr(97)) #将ASCII值转换成对应的字符
'''
def check_pwd(pwd):
low=0
up=0
num=0
if len(pwd)>=6 and len(pwd)<15:
#原生比较/ASII数值比较
for p in pwd:
##这里可参照ascii表来查明意义
if ord(p)>=97 and ord(p)<=122 :
# print('小写字母')
low+=1
elif ord(p)>=65 and ord(p)<=90 :
# print('大写字母')
up+=1
elif ord(p)>=48 and ord(p)<=57 :
# print('数字')
num+=1
else:
return False
#这里if判断,他们都通过了这些要求就给他们加1,如果最后的结果他们这几个条件都有1,则给它通过返回True
# print(low,up,num)
if up>=1 and low>=1 and num>=1:
return True
else:
# print("密码必须且只能由大小写字母和数字组成,长度为6~15位:")
# main.select()
return False
'''
手机号码的规则:按照标准的中国手机号码规则进行校验
'''
def check_tel(tel):
pattern = "^1[3-9]\d{9}$"
if(re.match(pattern,tel)):#固定写法,规则在线,字符串在后
return True
else:
# print("请按照中国手机号码输入你的手机号")
# main.select()
return False
##整体思路,就是将他们成功返回True,失败则返回False,这些有用,后面会使用到这些返回值。
三、数据库操作(db.py)
mysql(DML,DQL)
实现思路:
python:建立连接(字符编码),创建游标,sql查询,获取结果,关闭游标,关闭连接。
将注册信息,及修改用户信息,函数化写入数据库中,方便其他脚本调用
尽可能保证参数化,利用性强,模块化。
下方有校验需求注释👇
import pymysql##引用数据库内置模块
from pymysql import IntegrityError##引用内置函数
from safe14.mysql_system import main, storage##引入菜单及日志所有函数
def query(username):#查询,校验注册及登录
con=pymysql.connect(host='192.168.14.137',port=3306,user='root',password='123456',database='login',charset='utf8')
##pymysql.connect固定写法,后面根据格式要求输入对应的连接信息,和php有些不一样的点在于,直接在连接里面设置utf8编码格式
cursor=con.cursor()#拿着游标在做查询
sql=f"select password from user where username='{username}';"
##将sql语句参数化sql前面写个f里面的username给它用花括号参数化
cursor.execute(sql)#查sql语句的
results = (cursor.fetchone())##封装查询结果,fetchone一条,固定写法
if results is None:##如果查询结果是空
storage.stor("system.log", f"‘{username}’用户不存在,登陆失败")##写入日志系统
print(f"用户'{username}'不存在")##直接打印它不存在
##关闭查询,关闭数据数据库连接。保证占用资源损耗减少
cursor.close()
con.close()
main.select()##不存在的用户,直接给它返回至主菜单
else:##否则的话一定是直接成功,将results返回值取下标0直接取出来
resul = results[0] # 取一条数据
cursor.close()
con.close()
return resul#给个返回值
##下面判断密码和电话的逻辑完全相同
##定义好连接,然后定好游标及sql修改语句并参数化
##执行连接和sql语句/固定写法cursor.execute()
##!!重重之中记得提交//固定写法con.commit()
def dml_alter_pwd(password,username):#修改用户密码
con = pymysql.connect(host='192.168.14.137',port=3306,user='root',password='123456',database='login',charset='utf8')
cursor=con.cursor()
sql=f"update user set password='{password}' where username='{username}';"
cursor.execute(sql)
con.commit()#提交
def dml_alter_phone(tel,username):#修改用户电话号
con = pymysql.connect(host='192.168.14.137',port=3306,user='root',password='123456',database='login',charset='utf8')
cursor=con.cursor()
sql=f"update user set tel='{tel}' where username='{username}';"
cursor.execute(sql)
con.commit()#提交
def dml_insert(username,password,tel):#注册信息储存
con = pymysql.connect(host='192.168.14.137',port=3306,user='root',password='123456',database='login',charset='utf8')
cursor=con.cursor()
sql=f"insert into user(username,password,tel) values('{username}','{password}','{tel}');"
##这里注册信息用了个python报错异常处理try/except
try:
cursor.execute(sql)##执行
except IntegrityError as e:##将这条开头的报错信息as成e
if 'Duplicate' in str(e):##如果Dup在e报错里面
storage.stor("system.log", f"'{username}'用户已存在,请重新注册")##写入日志
print('用户名重复,注册失败')##给用户提示
else:##这里逻辑就简单了,如果里面没有用户传入的用户直接,else写数据库里
con.commit()#直接提交
storage.stor("system.log", f"用户'{username}'注册成功")##写入日志
print('注册成功')##提示成功
finally:##不论啥结果,直接返回至菜单。
main.select()
整体数据库脚本逻辑跑通很好写的。固定写法就那么几个
四、注册系统(regist.py)
实现思路:
代码量少的可怜即可完成注册。
正解且简单,直接引用四个脚本
这回之前check.py返回值的True 和 False直接用上了
下方有校验需求注释👇
from safe14.mysql_system import check##引用正则判断脚本
from safe14.mysql_system import storage##引用日志系统函数
from safe14.mysql_system import main##引用菜单
from safe14.mysql_system import db##引用数据库操作
def regist():
username = input('请输入用户名:')
if check.check_user(username)!=True:
storage.stor("system.log", f"用户名复杂度不符合要求,用户'{username}'注册失败")
print('用户名只能是大小写字母或数字,且不能以数字开头,长度为5~12位')
main.select()
password = input('请输入密码:')
if check.check_pwd(password)!=True:
storage.stor("system.log", f"密码复杂度不符合要求,用户'{username}'注册失败")
print('密码必须且只能由大小写字母和数字组成,长度为6~15位:')
main.select()
tel = input('请输入手机号:')
if check.check_tel(tel)!=True:
storage.stor("system.log", f"手机号不符合要求,用户'{username}'注册失败")
print('请按照中国手机号码输入你的手机号')
main.select()
##实现用户体验感极好,哪里规则输错了,直接给提示,前面三个if判断,哪里不符合规则,直接返回主菜单重新走一遍
##并且将失败注册并记录进日志文件中。
else:
db.dml_insert(username,password,tel)
##如果if全通过 直接 else,给他写入db文件,调用dml函数username,password,tel,insert插入数据库中。
##数据库有校验,如果有用户输入的用户,反之不让注册
五、登录系统(login.py)
实现思路:
主要有三大块函数:
登录校验,修改密码、电话判断,三次失败直接返回主菜单
改用户信息,需要登录后才可更改,为了不能随便让别人更改
下方有注释👇
import main
from safe14.study import check
from safe14.mysql_system import db, storage
def login1():#改密码
count = 0##定义个判断输错初始值
for i in range(3):#限定三次范围
username = input('请输入你的用户名:')
password = input('请输入你的密码:')
res = db.query(username)##请求一下数据库,看看有没有当前用户,锁定用户后面的用户信息也会跟着一起出来,结果res封装
if password != res:##这里不判断用户名,因为即便你随便输入的用户名,查找对应的密码信息,如果没有此用户,里面也没有随便输入的用户名的密码信息。
storage.stor("system.log", f"登录失败'{count+1}'次")##将登录失败次数记录在log日志中
print('登录失败')##给登录失败提示
count += 1##失败一次直接给+1次
if count == 3:##如果输错3次
storage.stor("system.log", f"登录失败共'{count}'次")##统计次数记录日志中
print('你已登录失败3次,请登录成功后再修改密码')##给提示
main.select()##直接给他返回至主菜单页面
count = 0##次数清零,解决下次循环出现报错清空
else:
count = 0
storage.stor("system.log", f"用户'{username}'登录成功,")##否则直接登录成功,并记录日志,次数给归零
newpassword = input('请输入你的新密码:')##输入新密码
if check.check_pwd(newpassword) == True:##这里再次调用密码校验正则判断
newwpassword = input('请再次输入你的新密码:')##再次输入一次密码,为了让用户输入密码别再忘了,用于用户新密码加深记忆
if newpassword == newwpassword:##如果新输入的密码等于重新输入的新密码
db.dml_alter_pwd(newwpassword, username)##直接将重新输入的新密码写入数据库,并且指定哪个用户的新密码
storage.stor("system.log", f"用户‘{username}’修改密码成功")##写入日志某某修改成功
print('密码修改成功')##给修改成功提示
main.select()##返回主菜单页面
else:##否则
storage.stor("system.log", f"2次输入的密码不一致,用户‘{username}’修改密码失败")##二次输入不一致,写入日志系统
print('2次输入的密码不一致,修改密码失败')##给用户提示
main.select()##直接回你老家吧,二次都失败了
else:##大if的判断,如果你输入的新密码不符合复杂度
storage.stor("system.log", "不符合密码复杂度要求,修改密码失败")##存入日志某某密码修改失败
print('不符合密码复杂度要求,修改密码失败')##给用户提示
main.select()##返回主菜单
###这里该菜单逻辑思路与 修改密码完全相同套路###不在做过多解释
def login2():#改电话
count = 0
for i in range(3):
username = input('请输入你的用户名:')
password = input('请输入你的密码:')
res = db.query(username)
if password != res:
storage.stor("system.log", f"登录失败'{count+1}'次")
print('登录失败')
count += 1
if count == 3:
storage.stor("system.log", f"登录失败共'{count}'次,")
print('你已登录失败3次,请登录成功后再修改密码')
main.select()
count = 0
else:
count = 0
storage.stor("system.log", f"用户'{username}'登录成功,")
newtel = input('请输入你的新号码:')
if check.check_tel(newtel) == True:
newwtel = input('请再次输入你的新号码:')
if newtel == newwtel:
db.dml_alter_phone(newwtel, username)
storage.stor("system.log", f"用户‘{username}’修改号码成功")
print('号码更改成功')
main.select()
else:
storage.stor("system.log", f"2次输入的号码不一致,用户‘{username}’修改号码失败")
print('2次输入的号码不一致,修改号码失败')
main.select()
else:
storage.stor("system.log", "不符合号码复杂度要求,修改号码失败")
print('不符合号码复杂度要求,修改号码失败')
main.select()
def loginfo():#包括登录成功和登录失败三次
count = 0##初始值给0
for i in range(3):##3次失败范围
username = input('请输入你的用户名:')
password = input('请输入你的密码:')
res = db.query(username)
if password != res:
storage.stor("system.log",f"登录失败'{count+1}'次")
print('登录失败')
count += 1
if count == 3:
storage.stor("system.log", f"登录失败共'{count}'次")
print('你已登录失败3次,返回主界面')
main.select()
count = 0
else:
storage.stor("system.log", f"用户‘{username}’登录成功")
print('登陆成功')
main.select()
count = 0
##整体思路如最上方一样,登录失败三次判断,记录日志,调用数据库用户信息数据,是否有。如果用户都写对,给他进入主菜单页面。
这里为了代码简洁直接login1()、login2() 了。
如果团队开发这边建议,标准函数命名,与其代码含义相关
函数格式如:驼峰
六、日志系统(storage.py)
实现思路:
调用个python内置时间模块
没什么思路逻辑,主要就是一个写入方法,前面做的记录,往日志函数里传值就行了
import time##调用time内置模块
def stor(file,cont):#日志记录,需要各个记录日志信息两个选项中的第一个传递传文件名参数,第二个就是其他记录变量信息传递给cont的参数。
##ymdHMS写出你想要的时间格式,time.time返回当前时间的时间戳,time.localtime格式化时间戳为本地的时间.
strtim = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
##time.strftime函数用于格式化时间,返回以可读字符串表示的当地时间
with open(file,'a+',encoding='utf8') as fp:##打开file文件参数,追加读写,设置utf8编码集,命名fp。
fp.write(strtim +' ' +cont+ "\n")##fp追写、然后就是日志格式了;时间在前+拼接中间空格隔开+记录字段阶段给个换行。
七、日志文件(system.log)
用于储存日志记录信息条目
2022-10-29 21:51:59 用户’admin’登录成功,
2022-10-29 21:52:10 密码错误,用户‘admin’登录失败‘1’次
2022-10-29 21:52:13 密码错误,用户‘admin’登录失败‘2’次
2022-10-29 21:52:15 密码错误,用户‘admin’登录失败‘3’次
2022-10-29 21:52:15 你已登录失败’4’次,
2022-10-29 21:55:23 用户‘admin’登录失败
2022-10-29 21:55:26 用户‘admin’登录失败
2022-10-29 21:55:30 用户‘admin’登录失败
2022-10-29 21:55:30 你已登录失败3次
2022-10-29 21:55:39 用户‘admin’登录失败
2022-10-29 22:07:45 登录失败’1’次
2022-10-29 22:07:48 登录失败’2’次
2022-10-29 22:07:50 登录失败’3’次
2022-10-29 22:07:50 登录失败’4’次
2022-10-29 22:08:12 登录失败’1’次
2022-10-29 22:08:14 登录失败’2’次
2022-10-29 22:10:26 登录失败’1’次
2022-10-29 22:10:30 登录失败’2’次
2022-10-29 22:10:30 登录失败’3’次
2022-10-29 22:11:22 密码复杂度不符合要求,注册用户‘admin’失败
2022-10-29 22:16:54 登录失败’1’次
2022-10-29 22:16:56 登录失败’2’次
2022-10-29 22:17:01 登录失败’3’次
2022-10-29 22:17:01 登录失败共’3’次
2022-10-29 22:17:47 登录失败’1’次
2022-10-29 22:18:05 用户‘admin’登录成功
2022-10-29 22:26:55 注册用户‘wangwu’成功
2022-10-31 09:31:31 用户‘admin’登录成功
全部文件
check.py(正则及ASII判断,注册信息校验)
db.py(数据库操作:DML,DQL/mysql)
login.py(登录系统及修改用户信息)
main.py(主页菜单)
regist.py(注册系统及校验引用)
storage.py(日志系统关键代码)
system.log(日志文件)
异常处理报错头排查方法:
1、查看代码引用时迷路使用ctrl+左键,追踪
2、多使用print打印出代码走向、多print有意无害
3、调用其他脚本函数引用文件,如找不到时点下红色灯泡
4、控制型代码注意缩进位置
5、调用函数,传参思路要明确过程及走向
总结
python控制台,实现用户注册、登录、修改密码、及各种校验
对注册登录系统交互初学者十分友好,对安全漏洞,本章无任何声明。
此篇文章纯手打,如有遗漏输错请包涵
希望能帮助到你