Python splitting code into functions
本问题已经有最佳答案,请猛点这里访问。
抱歉,这个长度,但我认为更多的信息比不够好!!
我正试图将(正在工作的)python代码分割成函数,以使其更清晰/更容易使用,但一旦我将这些代码转换成函数,它们就会失去联系。它基本上是一个密码生成器,它只在密码符合所有4个类别的字符条件时,尝试向用户输出密码。(小写、大写、数字和符号)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import random import string lowerasciis = string.ascii_letters[0:26] upperasciis = string.ascii_letters[26:] numberedstrings = str(1234567809) symbols ="!@$%^&*()[]" password_length = int(raw_input("Please enter a password length:")) while True: lowerasscii_score = 0 upperascii_score = 0 numberedstring_score = 0 symbol_score = 0 password_as_list = [] while len(password_as_list) < password_length: char = random.choice(lowerasciis+upperasciis+numberedstrings+symbols) password_as_list.append(char) for x in password_as_list: if x in lowerasciis: lowerasscii_score +=1 elif x in upperasciis: upperascii_score +=1 elif x in numberedstrings: numberedstring_score +=1 elif x in symbols: symbol_score +=1 # a check for the screen. Each cycle of the loop should display a new score: print lowerasscii_score, upperascii_score, numberedstring_score, symbol_score if lowerasscii_score >= 1 and upperascii_score >= 1 and numberedstring_score >= 1 and symbol_score >=1: password ="".join(password_as_list) print password break |
这是我试图分裂它的尝试。当我尝试运行下面的命令时,它会在scorepassword_中抱怨"unboundlocalerror:local variable'upperascii_score'referenced before assignment"as_a_list()函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import random import string lowerasciis = string.ascii_letters[0:26] upperasciis = string.ascii_letters[26:] numberedstrings = str(1234567809) symbols ="!@$%^&*()[]" password_length = int(raw_input("Please enter a password length:")) lowerasscii_score = 0 upperascii_score = 0 numberedstring_score = 0 symbol_score = 0 password_as_list = [] def genpassword_as_a_list(): while len(password_as_list) < password_length: char = random.choice(lowerasciis+upperasciis+numberedstrings+symbols) password_as_list.append(char) def scorepassword_as_a_list(): for x in password_as_list: if x in lowerasciis: lowerasscii_score +=1 elif x in upperasciis: upperascii_score +=1 elif x in numberedstrings: numberedstring_score +=1 elif x in symbols: symbol_score +=1 # give user feedback about password's score in 4 categories print lowerasscii_score, upperascii_score, numberedstring_score, symbol_score def checkscore(): if lowerasscii_score >= 1 and upperascii_score >= 1 and numberedstring_score >= 1 and symbol_score >=1: return 1 else: return 0 def join_and_printpassword(): password ="".join(password_as_list) print password while True: genpassword_as_a_list() scorepassword_as_a_list() if checkscore() == 1: join_and_printpassword() break |
这里的主要问题是,您需要跟踪正在使用的各种变量的范围。通常,将代码拆分为函数(如果操作得当)的好处之一是,可以重用代码,而不必担心是否在其他地方修改了任何初始状态。具体来说,在您的特定示例中,即使您使事情正常运行(使用全局变量),每次调用某个函数时,您都必须担心,例如
相反,您应该接受函数作为参数运行并输出一些返回值所需的任何内容,而不需要操纵全局变量。一般来说,这一想法被称为"避免副作用"。下面是重新编写的示例,请记住:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | import random import string lowerasciis = string.ascii_letters[0:26] upperasciis = string.ascii_letters[26:] numberedstrings = str(1234567809) symbols ="!@$%^&*()[]" def genpassword_as_a_list(password_length): password_as_list = [] while len(password_as_list) < password_length: char = random.choice(lowerasciis+upperasciis+numberedstrings+symbols) password_as_list.append(char) return password_as_list def scorepassword_as_a_list(password_as_list): lowerasscii_score = 0 upperascii_score = 0 numberedstring_score = 0 symbol_score = 0 for x in password_as_list: if x in lowerasciis: lowerasscii_score +=1 elif x in upperasciis: upperascii_score +=1 elif x in numberedstrings: numberedstring_score +=1 elif x in symbols: symbol_score +=1 # give user feedback about password's score in 4 categories return ( lowerasscii_score, upperascii_score, numberedstring_score, symbol_score ) def checkscore( lowerasscii_score, upperascii_score, numberedstring_score, symbol_score): if lowerasscii_score >= 1 and upperascii_score >= 1 and numberedstring_score >= 1 and symbol_score >=1: return 1 else: return 0 def join_and_printpassword(password_as_list): password ="".join(password_as_list) print password password_length = int(raw_input("Please enter a password length:")) while True: password_list = genpassword_as_a_list(password_length) current_score = scorepassword_as_a_list(password_list) if checkscore(*current_score) == 1: join_and_printpassword(password_list) break |
关于这方面的一些注意事项:
在python中进一步阅读变量范围和名称空间可能会很有用。这里有一个指南,但可能有更好的。