简体   繁体   中英

Is there a pythonic way to control the flow depending on kwargs in a function?

i have register_users list that have list of user objects and every user object have password, username, email property i want to create a login function that get a ** kwargs from input.

the kwargs input can be given to the function in 3 different ways.

  1. kwargs may have 3 keys username, password and email .

  2. kwargs may have 2 keys username or password .

  3. kwargs may have email or password .

in all the above we must check whether there is a user object in the register_user list whose information is the same as the given input or not.

And the question I have is What is the best way to determine how kwargs input is given?and how to do this with minimum use of if, ifelse ?or a pythonic way to do this.

class User:
    def __init__(self, username, password, email):
        self.username = username
        self.email = email
        self.password = password


user1 = User("user1", "user1@test.com", "test12345")
user2 = User("user2", "user2@test.com", "test12345")

register_users = [user1, user2]

def login(**kwargs):
    pass # determine how kwargs is given to function and then check informations

login({"username": "user1", "email": "user1@test.com", "password": "test12345"})
login({"username": "user1", "password": "test12345"})
login({"email": "user1@test.com", "password": "test12345"})

Logically, you always need the password, and either the username or email. A pythonic way is to retrieve these fields from kwargs and take advantage of this to validate the input parameter. From there you can use getattr to retrieve either the username either the email from the user.



def login(**kwargs):
     try:
         password = kwargs["password"]
         if "email" in kwargs:
             auth_field, auth_value = "email", kwargs["email"]
         else:
             auth_field, auth_value = "username", kwargs["username"]

     except KeyError:
         raise ValueError("Login requires password and either username or email")

     found_user = None
     for user in registered_users:
         if user.password == password and getattr(user, auth_field) == auth_value:
             found_user = user
             break

I assume that this is just for Stackoverflow, but in a real system you probably won't want to store your users in a list, and actual password checking will be slightly more complicated


EDITED to answer question in comment if we want to check either one of username/email, either both if they are both present


def login(**kwargs):
     try:
         password = kwargs["password"]
         auth_fields = {}
         if "email" in kwargs:
             auth_fields["email"] = kwargs["email"]
         if "username" in kwargs:
             auth_fields["username"] = kwargs["username"]

     except KeyError:
         raise ValueError("Login requires password and either username or email")

     found_user = None
     for user in registered_users:
         if user.password == password and all([getattr(user, field) == value for field, value in auth_fields.items()):
             found_user = user
             break

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM