You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:45:42