这篇文章将向你展示如何使用Python语言进行程序设计,实现一个简易的用户登录验证功能。
该功能允许用户输入由字母和数字任意组合而成的用户名和密码,并通过while循环不断地提示用户输入,直到凭证正确为止。所有凭证信息将被存储在一个字典中,以便进行匹配验证。
另外,引入了验证码机制,要求用户输入一个由0至9随机组成的四位数。无论登录尝试成功与否,此程序都会立即给出反馈,确保用户能够及时了解自己的登录状态。
用户登录验证的逻辑流程图源码import random# 数据库模拟,字典存放用户信息users_db = { "user-a": "123password", "user-b": "456password", "user-c": "789password"}# 该字典用于存放各个用户登录密码错误的次数login_count = {}def generate_captcha(): """生成四位数字的验证码""" return str(random.randint(1000, 9999))"""# 生成四位数验证码的另一种思路def generate_verification_code(): return ''.join([str(random.randint(0, 9)) for _ in range(4)])"""def verify_captcha(captcha_input, captcha_actual): """验证用户输入的验证码是否正确""" return captcha_input == captcha_actualdef user_login(): while True: """输入用户登录信息""" username = input("请输入用户名:") password = input("请输入密码:") # 生成验证码 captcha = generate_captcha() print(f"验证码是:{captcha}") captcha_input = input("请输入验证码:") # 用户名验证 if username in users_db: # 验证码验证 if not verify_captcha(captcha_input, captcha): print("验证码错误!") continue # 密码验证 if users_db[username] == password: print("登录成功!") break # 登录成功,退出循环 else:# 密码错误次数记录与锁定账号 if username in login_count: login_count[username] += 1 else: login_count[username] = 1 if login_count[username] >= 3: print("密码错误次数过多,账号已被锁定!") break # 输错三次密码,锁定账号,退出循环 else: print("密码错误!请重新输入!") else: print("用户名不存在,请重新输入!")if __name__ == "__main__": user_login()运行结果代码分析一、字典存放用户信息
字典是一种可变的容器模型,且可存储任意类型对象,用 { } 标识。字典是一个无序的键(key)值(value)对的集合。类似于,json对象存储格式
dic = {keyl = valuel, key2 = value2}二、验证码生成函数
def generate_captcha(): """生成四位数字的验证码""" return str(random.randint(1000, 9999))该函数的目的是生成一个四位数字的验证码。这个验证码是由随机生成的四位数组成,范围从1000到9999。
具体来说,代码的工作流程如下:
random.randint(1000, 9999):这行代码使用 random 模块的 randint 函数来生成一个位于1000和9999之间的随机整数,包括1000和9999。这意味着生成的验证码将是一个四位数。str(...):这个函数将生成的整数转换成字符串形式。因为验证码通常需要是字符串格式。# 生成四位数验证码的另一种思路def generate_verification_code(): return ''.join([str(random.randint(0, 9)) for _ in range(4)])这个函数generate_verification_code的目的是生成一个四位数的随机验证码。这个验证码由0到9的数字组成,每个数字都是随机选择的。
让我们分解这个函数来看它是如何工作的:
random.randint(0, 9):这个表达式会生成一个0到9(包括0和9)之间的随机整数。random是Python的标准库中的一个模块,它提供了生成随机数的函数。randint是random模块中的一个函数,用于生成一个指定范围内的随机整数。[str(random.randint(0, 9)) for _ in range(4)]:这是一个列表推导式,它将执行四次random.randint(0, 9)操作,生成四个随机数字。str()函数用于将每个生成的数字转换为字符串,因为我们需要的是字符串形式的数字,以便稍后可以连接成一个四位的字符串。''join(...):join是字符串的一个方法,它将列表中的所有元素连接成一个单一的字符串。在这个例子中,它将四个随机生成的字符串数字连接成一个四位的字符串。每次调用generate_verification_code函数时,它都会返回一个不同的四位随机验证码字符串。这个验证码可以用作登录验证的一部分,以确保尝试登录的用户是人类而不是自动化脚本。
三、格式化字符串字面量
在Python中,f-string是一种字符串字面量,它允许在字符串中嵌入表达式,并使用大括号{}来引用变量或者表达式。这种方式在Python 3.6及以上版本中可用,是一种非常方便和简洁的字符串格式化方法。
# 生成验证码captcha = generate_captcha()print(f"验证码是:{captcha}")captcha_input = input("请输入验证码:")这行代码print(f"验证码:{verification_code}")的作用是将变量verification_code的值嵌入到字符串中,并将其打印出来。这里的f表示这是一个格式化字符串,而{verification_code}告诉Python在这个位置插入verification_code变量的值。
当这行代码执行时,它会生成一个包含随机生成的验证码的字符串,并输出到控制台。
四、"main"函数与程序入口
对于很多编程语言来说,程序都必须要有一个入口,比如C,C++,以及完全面向对象的编程语言Java,C#等。
如果你接触过这些语言,对于程序入口这个概念应该很好理解,C,C++都需要有一个main函数作为程序的入口,也就是程序的运行会从main函数开始。同样,Java,C#必须要有一个包含Main方法的主类,作为程序入口。
而Python则不同,它属于解释型脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口。
一个Python源码文件(.py)除了可以被直接运行外,还可以作为模块(也就是库),被其他.py文件导入。不管是直接运行还是被导入,.py文件的最顶层代码都会被运行(Python用缩进来区分代码层次),而当一个.py文件作为模块被导入时,我们可能不希望一部分代码被运行。
所以,在Python中,if __name__ == "__main__":是一个常见的结构,用于确定模块是被直接运行还是被导入到另一个模块中。这里的__name__是Python的一个内置变量,它代表了当前模块的名称。
当一个模块被直接运行时,__name__的值会被设置为"__main__"。当一个模块被导入到另一个模块中时,__name__的值会被设置为该模块的名称。因此,if __name__ == "__main__":块中的代码只有在模块被直接运行时才会执行。这通常用于定义主程序入口点,即当模块作为脚本运行时应该执行的操作。
if __name__ == "__main__": user_login()这段代码意味着如果这个模块是作为主程序运行的,那么user_login()函数将被调用。这通常用于编写可复用的代码,既可以作为库导入到其他项目中,也可以作为独立的脚本运行。
例如,假设有一个名为my_module.py的文件,内容如下:
def user_login(): print("User logged in!")if __name__ == "__main__": user_login()如果直接运行my_module.py,输出将会是:
User logged in!但如果在其他模块中导入my_module,user_login()函数不会被自动调用:
import my_module# 这不会打印 "User logged in!",因为 my_module 被导入而不是直接运行这种结构是Python中常见的程序入口点定义方式,它允许模块的行为根据其是被直接运行还是被导入而有所不同。
作者:陈熙matoeffe链接:https://juejin.cn/post/7374055681890795555