python-3.x 通过对象的一个字段的值从集合中获取对象的有效方法

mwkjh3gx  于 2023-02-26  发布在  Python
关注(0)|答案(1)|浏览(138)

为以下函数提供以下可能输入之一:

  • ID(数字字符串)
  • 电子邮件(以@domain.tld结尾的字符串)
  • 名称(任何其他字母数字字符串,包括)

如果给定了ID以外的任何内容,它将尝试通过将给定属性与User对象列表中每个用户的相应字段进行比较来检索用户ID,所有User对象都具有ID字段。
例如,如果提供了一封电子邮件,它应该从用户列表中找到一个在其电子邮件字段中具有给定电子邮件的用户,然后从该用户的ID字段返回值。
在Django中看起来像User.objects.filter(email=input_string).first()
在我的代码中,下面这行代码就是这样做的:user := next((user for user in users if user.email == input_string)
它看起来不太理想,也很难看,但我正在努力寻找一个更整洁的解决方案。
希望你能给点建议。

def validate_user_id(input_string, users):
    if input_string.isdigit():
        return {'type': 'user', 'id': input_string}
    elif input_string.endswith(MAIL_DOMAIN):
        if user := next((user for user in users if user.email == input_string), None):
            return {'type': 'user', 'id': user.id}
        return None
    elif (input_string.isalnum() or
          ''.join(input_string.split('.')).isalnum()):
        if user := next((user for user in users if user.nickname == input_string), None):
            return {'type': 'user', 'id': user.id}
        return None
    raise ValueError(
        MEMBER_FORMAT_INVALID.format(identifier=input_string))
fsi0uk1n

fsi0uk1n1#

若要使代码更加DRY和优化,请使用以下方法:

  • 检查输入字符串格式以识别用户的目标属性
  • 而不是整个user对象从生成器表达式产生user.id
def validate_user_id(input_str, users):
    if input_str.isdigit():  # base case
        return {'type': 'user', 'id': input_str}

    if input_str.endswith(MAIL_DOMAIN):
        attr = 'email'
    elif (input_str.isalnum() or
          ''.join(input_str.split('.')).isalnum()):
        attr = 'nickname'
    else:
        raise ValueError(MEMBER_FORMAT_INVALID.format(identifier=input_str))

    user_id = next((user.id for user in users
                    if getattr(user, attr) == input_str), None)
    if user_id:
        return {'type': 'user', 'id': user_id}
    return None

相关问题