Python函数使用代码纠错求助:新手程序运行异常排查
问题描述
我是Python及编程领域的纯新手,这是我第一次使用函数编写代码。非常感谢任何帮助,我的目标并非写出最优雅或最高效的代码,只希望它能正常运行即可。😅
我编写了以下程序,但无法让它正常运行。由于这是大学的计分作业,我需要遵守一些限制要求:
import re import sys # get the filename filename = sys.argv[1] # open a file for reading infile = open(filename, 'r') ######################################################################################## # function to return just the consonants in a given namecdef get_consonants(y): def get_consonants(y): only_consonants_sep = re.findall('[^\\W_aeiou]', y) only_consonants = ''.join(only_consonants_sep) return only_consonants ######################################################################################## # function to return first and last name according to all rules def parse_name(input_y): # Parse the names to first (meaning first+middle, if it exists) and last names for element in input_y: # define last name for later use last_namegroup = re.search('(\\w*)\\t', element) last_name = last_namegroup.group(1) # define what the middle name is for later use middle_namegroup = re.search('\\s(\\w)', element) middle_name = middle_namegroup.group(1) # define what first name is for later use first_namegroup = re.search('^(\\S*)', element) first_name1 = first_namegroup.group(1) # if length of consonant_first_middle is still larger than 8 # take the consonants of only the first name # and add the first letter of the middle name defined above if len(consonant_first_middle) > 8: consonant_first_name = get_consonants(first_name1) first_name = (f'{consonant_first_name}{middle_name}') # if there is no middle name, i.e. only ones white space in the line # then just take the word until the space and store it as first_name else: first_namegroup = re.search('^(\\S*)', element) first_name = first_namegroup.group(1) return(first_name, last_name) ######################################################################################## # creating the email addresses def create_email_address(first_name, last_name): for lines in infile: if re.search('\\tstu', lines): domain = (f'{first_name}.{last_name}@uzh.ch') else: domain_part = re.search('\\t(.*)$',lines) domain = (f'{first_name}.{last_name}@{domain_part.group(1)}.uzh.ch') return domain ######################################################################################## # function as the "top level" of the program that calls all other functions as needed. def main(): ####### Receive a file name from the command line # get the filename filename = sys.argv[1] # open a file for reading infile = open(filename, 'r') ####### Normalise the input input_normalized = normalize(infile) ####### Parse the names as needed input_first, input_last = parse_name(input_normalized) ####### Create email addresses email_output = create_email_address(input_first, input_last) ####### Print the result for line in infile: print(f'{line} --> {email_output}') main_function = main() print(main_function)
我认为问题出在代码中的文件迭代逻辑上,但我无法找出具体错误。希望你能指出问题所在,非常感谢!
问题分析与修正建议
核心问题点:
- 文件指针耗尽:你在全局、
main、create_email_address里多次操作同一个文件对象,create_email_address遍历完所有行后,文件指针移到末尾,后续main里再遍历文件就没有内容了。应该一次性读取所有行到列表,再传递给函数处理。 - 未定义变量:
parse_name里用到的consonant_first_middle没有定义,直接会触发NameError,需要先计算名字的辅音组合再做判断。 - 匹配异常风险:
middle_namegroup、last_namegroup如果没找到匹配(比如无中间名、格式错误),调用group(1)会抛出AttributeError,必须先检查匹配是否存在。 - 循环逻辑错误:
parse_name和create_email_address的循环都只保留最后一次迭代的结果,没有处理每一行数据,应该逐行生成对应结果。 - 缺失函数:
normalize函数未定义就直接调用,会报错,要么补充实现要么移除调用。 - 缩进错误:
parse_name里的if语句缩进完全错误,导致语法错误,需调整缩进层级。 - 主函数调用冗余:
main没有返回值,赋值给main_function再打印会输出None,直接调用main()即可。
修正后的核心逻辑示例
import re import sys def get_consonants(y): # 匹配辅音(忽略大小写) only_consonants_sep = re.findall(r'[^_\Waeiou]', y, re.IGNORECASE) return ''.join(only_consonants_sep) def parse_name(line): # 提取姓氏(制表符前的内容) last_name_match = re.search(r'(.*?)\t', line) last_name = last_name_match.group(1).strip() if last_name_match else '' # 拆分名字部分(可能包含中间名) name_part = line.split('\t')[0].strip() name_parts = name_part.split() first_name = name_parts[0] middle_initial = name_parts[1][0] if len(name_parts) > 1 else '' # 处理名字长度规则 consonant_first = get_consonants(first_name) consonant_combined = consonant_first + middle_initial # 这里可以根据需求调整长度判断逻辑 final_first = consonant_combined[:8] if len(consonant_combined) >8 else consonant_combined return final_first, last_name def create_email_address(first_name, last_name, line): first_name_lower = first_name.lower() last_name_lower = last_name.lower() if '\tstu' in line: return f"{first_name_lower}.{last_name_lower}@uzh.ch" else: domain_match = re.search(r'\t(.*)$', line) domain_part = domain_match.group(1).strip().lower() if domain_match else '' return f"{first_name_lower}.{last_name_lower}@{domain_part}.uzh.ch" def main(): if len(sys.argv) <2: print("请提供文件名作为命令行参数") return filename = sys.argv[1] # 一次性读取所有行,避免指针问题 with open(filename, 'r', encoding='utf-8') as infile: lines = [line.strip() for line in infile if line.strip()] for line in lines: first_name, last_name = parse_name(line) email = create_email_address(first_name, last_name, line) print(f"{line} --> {email}") if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者ling_666
相关产品推荐
相关产品推荐

