将两个相似的功能重构为一个?

时间:2019-12-11 14:24:10

标签: python python-3.x

我有一个非常简单的注册/登录程序,用于学习目的,并且可以正常工作。但是感觉就像我有重复的代码。必须显而易见的是检查功能。

我的问题是,我应该重构这两个文件以便它们合而为一吗?还是最好让它们分开?

def signUp():
    username = input("Give me a username: ")

    if checkUser(username) == True:
        print("You are already registrered, please log in with your password.")
    else:
        password = input("Also give me a password: ")
        with open("sign-up.csv", "a", newline="") as file:
            writer = csv.writer(
                file, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL
            )
            writer.writerow([username, password])
            print("You are now signed up. Please log in with your credentials.")


def logIn():
    username = input("Give me your username: ")
    password = input("Also give me your password: ")
    if checkPassword(username, password) == True:
        print("Welcome, you are now logged in.")
    else:
        print("Username or password is incorrect please try again.")


def checkUser(username):
    with open("sign-up.csv", "r") as file:
        reader = csv.reader(file)
        myList = dict(reader)
        if username in myList:
            return True
        else:
            return False


def checkPassword(username, password):
    with open("sign-up.csv", "r") as file:
        reader = csv.reader(file)
        myList = dict(reader)
        if username in myList and password == myList[username]:
            return True
        else:
            return False


def get_user_choice():
    print("\n[1] Sign up")
    print("[2] Log in")
    print("[q] Quit")

    return input("What would you like to do? ")


choice = ""
while choice != "q":
    choice = get_user_choice()
    if choice == "1":
        signUp()
    elif choice == "2":
        logIn()
    elif choice == "q":
        print("Welcome back some other day")
    else:
        print("That choice doesn't exists")

4 个答案:

答案 0 :(得分:2)

函数checkUser正在检查csv文件中是否已经存在用户名。这将在注册时发生。当用户登录时使用功能checkPassword。这些功能应保持独立,因为它们在安全级别不同方面做的事情大不相同。他们还根据用户在注册/登录过程中的位置来期望输入。这意味着当您编写一个与doBoth(username, password)都一样的函数时,要在应用程序doBoth(username, null)的注册时使用该函数,必须使用null调用此函数,因为在注册时从未知道密码。 / p>

答案 1 :(得分:1)

第一个显而易见的分解是这两个函数的共同部分-该部分将csv文件读入字典:

def read_users():
    with open("sign-up.csv", "r") as file:
        reader = csv.reader(file)
        return dict(reader)

然后您可以使用以下功能重写check_user和check_password:

def check_user(username):
    users = read_users()
    return username in users


def check_password(username, password):
    users = read_users()
    # make sure we work correctly even if
    # someone passes `None` as password
    _notfound = object()
    return users.get(username, _notfound) == password

FWIW,最好将这些函数命名为(分别)“ user_exists”和“ authenticate”

此外,您可能希望排除正在写入csv文件的部分-不是减少代码重复,而是更好地分离UI /域/持久性层。

def add_user(username, password):
     with open("sign-up.csv", "a", newline="") as file:
         writer = csv.writer(
           file, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL

         writer.writerow([username, password])


def sign_up():
    username = input("Give me a username: ")

    # note how good naming makes code much more explicit
    if user_exists(username):
        print("You are already registrered, please log in with your password.")
        return # no need to go further

    password = input("Also give me a password: ")    
    add_user(username, password)



def log_in():
    username = input("Give me your username: ")
    password = input("Also give me your password: ")
    if authenticate(username, password):
        print("Welcome, you are now logged in.")
        return

    # oops...
    print("Username or password is incorrect please try again.")

下一步是用专用的input()ask_username()函数替换ask_password()调用,这些函数将验证用户的输入。首先,尽可能简单地编写它们,然后找出通用部分,看看是否可以将它们排除在外。

请注意,我在all_lower中重命名了您的函数-这是the official coding convention,Python用户倾向于强烈遵守官方的编码约定。

还要注意,我删除了无用的== True测试。在Python中,任何表达式都解析为一个对象(在函数调用的情况下,解析为该函数返回的对象),并且每个对象都有一个布尔值,因此if someexpression == True:最多是多余的。 FWIW也是pep8(官方编码约定)的一部分。最后,当您发现自己写的东西是:

if someexperession:
   return True
else:
   return False

您可以将其简化为

return someexpression

答案 2 :(得分:0)

尝试一下:

def checkBoth(username, password):
    with open("sign-up.csv", "r") as file:
        reader = csv.reader(file)
        myList = dict(reader)
        if username in myList:
            u = True
            if password == myList[username]:
                p = True
            else:
                p = False
        else:
            u = False
            p = False

        return (u,p)

答案 3 :(得分:0)

def checkPassword(username, password):
out = [False, False]
    with open("sign-up.csv", "r") as file:
        reader = csv.reader(file)
        myList = dict(reader)
        if username in myList:
            out[0] = True
            if password == myList[username]:
                out[1] = True
    return out

,然后检查一下什么是正确的。