有没有办法让我的代码更有效率

Is there a way to make my code more effiecient

提问人:Big_Port 提问时间:7/26/2023 最后编辑:Wiktor StribiżewBig_Port 更新时间:7/27/2023 访问量:73

问:

嘿,所以我是一个初学者,只是为了变得更好而尝试项目,所以我做了一个密码检查器。 只是想看看是否有我可以让我的代码更整洁或更有效率的提示很好。

import re
regex = re.compile('[@_!#$%^&*()<>?/\|}{~:]')

while True:
    pw = input("Enter a string: ")
    if 5<=len(pw)<=10:
        if (regex.search(pw) == None):
            print("Not a valid password, Needs special character")
            continue
        else:
            if any(x.isupper() for x in pw):
                print("character has an uppercase letter")
                return True
            else:
                print("Character does not have an upper case")
                continue
    else:
        print("password must be between 5 and 10 characters")
        continue

要把它放到一个函数中,在main里面,True返回它是有效的

python-3.x 验证 if 语句 密码

评论

1赞 Vlad Mashkautsan 7/26/2023
看起来很有效,但即使不是,它也足够简单,永远不会运行缓慢
5赞 Sayse 7/26/2023
代码审查
2赞 Ted Lyngmo 7/26/2023
这可能更适合代码审查,并作为代码审查说明:对密码进行长度限制不是一个好主意。如果用户需要,让它成为数十亿个字符。无论如何,除了哈希密码之外,您永远不必存储任何东西。

答:

-1赞 Piotr Żak 7/26/2023 #1

是的,在 start 的变量中定义所有条件(业务需求):

isUpperCaseCriteria = any(char.isupper() for char in text)
isSpecialCharacterCriteria = any(char in string.punctuation for char in text)
isLengthCriteria = len(text) >= 10


if isUpperCaseCriteria:
   -> code 
if isSpecialCharacterCriteria:
   -> code
if isLengthCriteria:
   -> code

然后检查一切。

这不是提高效率,而是可读性。 从维护此代码的角度来看,这几乎是一样的。

评论

0赞 Codist 7/26/2023
你能把这些“技术”放到实际可以运行的东西中吗?伪代码对答案没有帮助
0赞 Big_Port 7/26/2023
同意 darkKnight,因为 isUppercase 仅在所有字符都是大写而不是只有一个大写时才有效
0赞 Piotr Żak 7/26/2023
对不起,伙计们,我不想说明OP的概念。我一会儿会编辑帖子。
0赞 Piotr Żak 7/26/2023
也许这是要求之一,每个字符串都是大写的?好像有人在喊xd
0赞 Codist 7/26/2023
原则上,这是低效的。例如,如果 isUpperCaseCriteria 为 False,则不应执行其他测试,因为您已经确定密码无效
0赞 BlizZ 7/26/2023 #2

首先,我认为不推荐这种方法,因为它在 C 等其他语言中可能不可行。

if 5 <= len(pw) <= 10:

使用类似这样的东西

if len(pw) < 5 or len(pw) > 10:

我相信试图避开别人是更好的方法。你可以通过只使用一个语句和如下所示的语句来实现这一点:Ifcontinue

if len(pw) < 5 or len(pw) > 10:
    print("password must be between 5 and 10 characters")
    continue

缩进越少,代码就越容易读取和调试。

与其使用无限循环,不如尝试使用布尔变量,例如使条件更易于理解。while True:isCorrectPassword

最后,我认为 Stack Overflow 不是用于代码审查,而是用于调试目的。您应该尝试 Stack Exchange。

评论

0赞 liakoyras 7/27/2023
“首先,我认为不推荐这种方法,因为它在 C 等其他语言中可能不可行。” 哈哈,我已经写 python 多年了,甚至不知道这在 Python 中是可能的。
1赞 BlizZ 7/27/2023
啊哈,这对我来说也是一个发现。
0赞 Codist 7/26/2023 #3

对于这样短暂的东西,在运行时效率方面几乎没有什么好处。

但是,您可以考虑进行一些更改,以改进代码结构。

首先,您应该编写一个执行验证的函数 - 并且仅此而已。这样,无论从哪里获取密码,您都可以始终使用相同的功能。

特殊字符字符串看起来很笨拙,所以把它放在一个全局变量中(我通常使用大写的变量名称来表示全局范围以及它的使用是常量的事实)。像这样的东西:

SPECIALS = '[@_!#$%^&*()<>?/\\|}{~:]'

def validate(password):
    if 5 <= len(password) <= 10: # correct length
        if any(sc in password for sc in SPECIALS): # has a special character
            if any(c.isupper() for c in password): # has at least one uppercase letter
                return True
    return False

while True:
    password = input('Enter a password: ')
    if validate(password):
        print('Valid')
        break
    print('Invalid - try again')
2赞 Sash Sinha 7/26/2023 #4

这是对原始代码进行一些改进的又一次尝试:

import re
import getpass

from typing import NamedTuple


class ValidationResponse(NamedTuple):
    is_valid: bool
    message: str


MIN_LENGTH = 5
MAX_LENGTH = 10
SPECIAL_CHARS = "[@_!#$%^&*()<>?/\|}{~:]"
SPECIAL_CHARS_REGEX = re.compile(SPECIAL_CHARS)


def validate_password(password: str) -> ValidationResponse:
    """
    Validate password based on predefined rules.

    This function checks a given password for compliance with the following rules:
    - The password should be between MIN_LENGTH and MAX_LENGTH characters long.
    - The password should contain at least one character from SPECIAL_CHARS.
    - The password should contain at least one uppercase letter.

    Args:
        password (str): The password string to be validated.

    Returns:
        ValidationResponse: A named tuple with the following fields:
            - is_valid (bool): True if the password is valid, False otherwise.
            - message (str): The validation message.
    """
    if not MIN_LENGTH <= len(password) <= MAX_LENGTH:
        return ValidationResponse(
            False,
            f"Password must be between {MIN_LENGTH} and {MAX_LENGTH} characters.",
        )
    if SPECIAL_CHARS_REGEX.search(password) is None:
        return ValidationResponse(
            False,
            f"Password needs to contain at least one special character {SPECIAL_CHARS}",
        )
    if not any(char.isupper() for char in password):
        return ValidationResponse(
            False,
            "Password needs to contain at least one uppercase letter.",
        )
    return ValidationResponse(True, "Password is valid.")


def main() -> None:
    while True:
        password = getpass.getpass("Enter a password: ")
        is_valid, message = validate_password(password)
        print(message)
        if is_valid:
            break
    print(f"DEBUG: {password} is valid!")


if __name__ == "__main__":
    main()

带有解释的改进:

  1. 关注点分离:用户输入收集和密码验证现在在两个不同的函数中处理。该函数要求用户输入密码,并检查提供的密码是否符合指定的条件。这使得代码模块化,易于理解,并提高了可重用性。mainvalidate_password

  2. 常量的使用:常量 、 、 和 用于定义密码要求。这使得代码更易于维护,因为这些要求可以在一个地方轻松更改,而无需遍历整个代码。MIN_LENGTHMAX_LENGTHSPECIAL_CHARSSPECIAL_CHARS_REGEX

  3. 类型提示:该函数现在包含输入和返回值 () 的类型提示 ()。这使得代码更易于理解和使用,尤其是在较大的代码库中或与其他开发人员协作时。validate_passwordpassword: str-> ValidationResponse

  4. 安全密码输入:现在使用 getpass 模块捕获密码,该模块不会将密码回显到控制台,从而提供额外的安全层。

  5. 清除通信:每次检测到密码问题时,它都会立即返回一个 False 标志和一条消息,解释密码无效的原因。这使得调试更容易,并为用户提供明确的反馈。validate_password

  6. 终止:函数循环运行,直到输入有效密码。一旦检测到有效密码,循环就会中断,并显示一条成功消息。这样,程序会提供持续的反馈,直到收到有效的输入。main

我希望这对:)有所帮助