【问题标题】:Python can't find element that's therePython 找不到存在的元素
【发布时间】:2021-12-06 18:28:05
【问题描述】:

首先,Python 不是我的第一语言,但我正在学习的一门课程需要它,所以我在这里......我正在使用 python 和烧瓶来制作一个简单的登录/注册网站页。制作页面很简单(我认为?),但是在设置注册标准时,我用来检查用户是否已经存在的 for 循环起初工作,但没有更改代码,它不再起作用。我输入“admin”作为用户名,但尽管存在于 txt 文件中,但循环找不到它。我是疯了还是错过了什么?

def info():
    with open('passfile.txt', "r") as f:
        lines = f.readlines()
        for line in lines:
            text = line.split()
            username = text[0]
            print(text[0])
            password = text[1]

            yield username, password

def add_info(username, password):
    with open('passfile.txt', "a") as f:
        f.write(username + " " + password +"\n")


@week6.route("/registration", methods=["GET", "POST"])
def register():
    """
    function to register a new user
    """
    username, password = info()

    if request.method == "POST":
        un = request.form.get("username")
        pw = request.form.get("password")
        secure = sc.hash(str(pw))
        register.secure = secure
        print(un)
        if un in username:
            flash("That username is already taken")
            return render_template("registration.html")
        
        if pw_verify(pw) == True:
            add_info(un, secure)
            flash("Your officially registered!")
                
    return render_template("registration.html")

【问题讨论】:

  • 是缩进不对还是我不对?
  • 缩进是对的。由于某种原因,stackoverflow 代码格式化程序搞砸了
  • username 是一个迭代器,它返回 (username, password) 对。然后你不能测试if un in username,因为一个字符串不匹配一对。
  • 如果这里的缩进没有复制你的实际缩进,edit你的问题并解决它。
  • 现在应该修复缩进

标签: python for-loop text


【解决方案1】:

您的问题在于您如何使用生成器功能:

def info():
    ...
    for line in lines:
        ...
        yield username, password

然后:

username, password = info()

第一个函数的作用(一个生成器函数,因为它使用 yield 而不是 return)是返回一个迭代器,当您对其进行迭代时,它会为您提供 (username, password) 元组。

当您将其称为username, password = info() 时,您将对其进行两次迭代并将这些元组分配给usernamepassword

所以,username 可能是 ("user1", "secret_password")password 可能是 ("admin", "admin_password"),这显然不是您想要的。

看起来您希望info 执行的操作是返回用户名列表和密码列表。像这样更改它可以使用您的代码:

def info():
    usernames = []
    passwords = []
    with open('passfile.txt', "r") as f:
        for line in f.readlines():
            username, password = line.split(maxsplit=1)

            usernames.append(username)
            passwords.append(password)

    return usernames, passwords

虽然可以快速解决,但我认为这可能不是解决此问题的最佳方法。

【讨论】:

    【解决方案2】:

    使用yield 将函数转换为生成器。这意味着 info 实际上返回一个迭代器。第一步是将您的info 调用更改为:

    users = info()
    

    迭代器动态计算它们的值,因此in 运算符不能与它们一起使用。您需要使用迭代器来查看其内容。您可以修改 if 语句以使用 any 函数和推导式。

    if any(u[0] == un for u in users):
    

    理解产生一个基于从info 产生的元组的第一个元素的布尔值。如果任何元素为真,any 函数将返回 True。

    【讨论】:

      猜你喜欢
      • 2016-04-18
      • 1970-01-01
      • 2021-12-17
      • 2018-11-07
      • 2019-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多