原文链接:http://www.juzicode.com/python-tutorial-login-system/
到目前为止已经介绍了Python的基本数据类型,基本输入输出系统以及条件语句、循环语句,这些类型构成了一种计算机语言的最基本要素,我们接下来综合运用这些知识设计一套登录系统,这个系统做了些简化,采用基本输入输出作为用户名和密码的输入,密码和用户名保存在代码中,每次提示用户输入用户名和密码,然后和代码中保存的用户名和密码进行比对,如果匹配上就提示可以登录系统,失败就提示重新输入,如果失败达到一定次数就提示强制退出。
1 用户名和密码的保存
从前面的基本数据类型的特点看,可以选用list,tuple或者set定义2组数据,假设使用list,list_user保存用户名,list_pswd保存密码,相同位置作为一对用户名和密码,但是这种方式使用起来还是不太方便,因为需要根据输入的用户名查找list_user下标,再用这个下标去查找list_pswd对应下标的值,判断这个值是否和输入的密码相同。
list_user['orange','apple','banana']
list_pswd['juzicode','123','456']
但是如果选用dict类型时,用key保存用户名,value保存密码,这样每次用输入的用户名作为key,找到这个key对应的value是否和输入的密码相同,这样代码更加简洁易懂。从这个例子我们也可以看出选择合适的数据类型,对程序设计和编码是非常有利的。
user_dict = {'orange':'juzicode','apple':'123','banana':'456'}
2 流程控制结构
因为在比对用户名和密码时,失败需要重新输入,如果使用条件语句,只能判断一次就要退出了,所以需要用到循环结构。在循环语句中判断,如果比对上就退出系统,如果比对失败,再次回到循环开始提示输入用户名和密码。这样循环语句就要用到while True语句,在循环体中进行判断,满足比对成功或者输入错误达到一定次数就break退出。
3 实现step1
第一步先实现一个简单的程序,用user_dict保存用户名和密码对,先提示输入用户名和密码,先用条件语句判断,如果用户名存在,就判断密码是否和这个用户名对应的密码是否相同,并提示是否输入正确。
print('-----欢迎来到www.juzicode.com')
print('-----公众号: juzicode/桔子code\n')
user_dict = {'orange':'juzicode','apple':'123','banana':'456'} #这里用字典的key保存了用户名,字典的value保存密码
user = input('请输入用户名: ')
pasw = input('请输入密码: ')
if user not in user_dict:
print('你输入的用户名不存在')
else:
if user_dict[user] == pasw:
print('密码正确,进程系统......')
else:
print('密码错误,拒绝进入!')
结果 | 第一次运行,输入不存在的用户名abc —–欢迎来到www.juzicode.com —–公众号: juzicode/桔子code 请输入用户名: abc 请输入密码: a 你输入的用户名不存在 第2次运行,输入正确的用户名orange,输入错误的密码xxx 请输入用户名: orange 请输入密码: xxx 密码错误,拒绝进入! 第3次运行,输入正确的用户名orange,输入正确的密码juzicode 请输入用户名: orange 请输入密码: juzicode 密码正确,进程系统…… |
4 实现step2
上面的实验实现了单次的输入比对,还不能满足如果输入错误的的用户名密码重试的功能,从前面的分析看需要用到循环语句,循环语句的位置应该是在提示用户输入用户名和密码的地方,起始加一行while True就能满足基本的要求:
print('-----欢迎来到www.juzicode.com')
print('-----公众号: juzicode/桔子code\n')
user_dict = {'orange':'juzicode','apple':'123','banana':'456'} #这里用字典的key保存了用户名,字典的value保存密码
while True: #新加入的循环条件语句
user = input('请输入用户名: ') #基本输入函数,获取用户名,得到一个字符串类型的变量
pasw = input('请输入密码: ')
if user not in user_dict: #检查某个值是否是dict的一个元素,如果不是(not in)提示用户名不存在
print('你输入的用户名不存在')
else: #如果用户名存在,判断密码是否正确
if user_dict[user] == pasw: #字典元素的引用,dict[key]
print('密码正确,进程系统......')
else:
print('密码错误,拒绝进入!')
运行上面的代码,发现好像永远都无法退出这个循环体,因为在这个循环体里面,没有加入退出语句,不管输入正确与否都不能退出。
5 实现step3
因为要求在输入正确的用户名和密码后要退出循环,但是循环条件里用的是while True,所以要在循环体中合适的位置使用break语句。而且上面的循环中也没有对输入错误次数进行判断,所以还需要再新增一个dict变量retry_count,用来保存对应的用户名输入的错误次数,如果输入的用户名在user_dict里,retry_count增加该用户名的元素,并且初始化为0,如果输入一次错误的密码,该用户名key对应的value加1,当输入的错误次数大于3的时候,就用break语句跳出循环,并提示输入错误,拒绝进入系统,如果输入正确就提示正在进入系统:
user_dict = {'orange':'juzicode','apple':'123','banana':'456'} #这里用字典的key保存了用户名,字典的value保存密码
retry_count = {} #重试次数
while True:
user = input('请输入用户名: ') #基本输入函数,获取用户名,得到一个字符串类型的变量
pasw = input('请输入密码: ')
if user not in user_dict: #检查某个值是否是dict的一个元素,如果不是(not in)提示用户名不存在
print('你输入的用户名不存在')
else: #如果用户名存在,判断密码是否正确.
retry_count.setdefault(user,0) #字典的setdefault操作,如果不存在user的key,新加key=user并设置为0
if user_dict[user] == pasw: #字典元素的引用,dict[key]
print('密码正确,进入系统......')
break #如果密码正确,跳出循环
else:
retry_count[user] = retry_count[user]+1 #错误次数加1
print('密码错误,拒绝进入!')
print('user=%s已错误输入%d次! '%(user,retry_count[user]))
if retry_count[user] >= 3:
print('输入的错误次数已达最大次数,退出!')
break
6 实现step4
前面的代码if语句嵌套了多层,从视觉观感上不是很好,因为随着嵌套的深入,看代码的时候就需要过分关注if语句缩进的层次,特别是在缩进更多层次、代码行数暴增的时候,代码的可读性就会明显变差。一种通用的做法就是在循环体中的前半部分做错误处理,如果不满足某个条件,就使用continue语句,跳过本轮循环后面的语句,这样代码看起来就更加紧凑些,修改后的代码是这样的:
print('-----欢迎来到www.juzicode.com')
print('-----公众号: juzicode/桔子code\n')
user_dict = {'orange':'juzicode','apple':'123','banana':'456'} #这里用字典的key保存了用户名,字典的value保存密码
retry_count = {} #重试次数
while True:
user = input('请输入用户名: ') #基本输入函数,获取用户名,得到一个字符串类型的变量
pasw = input('请输入密码: ')
if user not in user_dict: #检查某个值是否是dict的一个元素,如果不是(not in)提示用户名不存在
print('你输入的用户名不存在')
continue
#如果用户名存在,判断密码是否正确.
retry_count.setdefault(user,0) #字典的setdefault操作,如果不存在user的key,新加key=user并设置为0
if user_dict[user] == pasw: #字典元素的引用,dict[key]
print('密码正确,进入系统......')
break #如果密码正确,跳出循环
#如果用户名密码不匹配,相应的错误次数统计加1
retry_count[user] = retry_count[user]+1 #错误次数加1
print('密码错误,拒绝进入!')
print('user=%s已错误输入%d次! '%(user,retry_count[user]))
if retry_count[user] >= 3:
print('输入的错误次数已达最大次数,退出!')
break
运行效果:
示例代码:https://github.com/juzicode00/py3study/tree/master/sy01-登录系统