Python中传递f-string作为参数报错的解决方法
问题解答
核心结论
完全可以用f-string作为DictWriter.writerow()的参数值——f-string本质就是普通字符串,和直接传入字符串变量、字面量没有区别,这不是你报错的原因。
报错原因分析与修正
你遇到的SyntaxError: closing parenthesis ')' does not match opening parenthesis '{'从提供的代码看语法上不存在,但代码有两个关键问题,其中作用域问题会引发运行时错误,逻辑优先级问题可能导致结果不符合预期:
1. 作用域错误:writer变量无法在函数内访问
你在with open(...) as csvfile:块内定义的writer是局部变量,块结束后变量就会被销毁。当wdraft函数调用writer.writerow(row)时,会找不到这个变量,引发NameError。
解决方法:将writer作为参数传入wdraft函数,或者把函数定义移到with块内部。
2. 逻辑运算符优先级问题
你的判断条件:
if 'AP: 1st Tm' in row['All-pro teams'] or 'AP: 2nd Tm' in row['All-pro teams'] and row['Pos'] not in specialists:
由于and优先级高于or,实际逻辑会变成:('AP: 1st Tm' 在列表中) 或者 (('AP: 2nd Tm' 在列表中) 且 (位置不在特殊列表)),这大概率不符合你的预期。
修正:给两个in判断加上括号,确保逻辑正确:
if ('AP: 1st Tm' in row['All-pro teams'] or 'AP: 2nd Tm' in row['All-pro teams']) and row['Pos'] not in specialists:
3. 额外优化建议
- 输出文件名加上
.csv后缀,避免文件格式识别问题 - 每次处理年份前重置分区计数,否则会累加之前的结果
- 简化跨队情况的判断逻辑,避免重复的elif分支
修正后的完整代码
import csv import matplotlib.pyplot as plt specialists = {'ST', 'LS', 'KR', 'PR', 'K', 'P'} # 重置分区计数,确保每次处理年份都是全新统计 def reset_divisions(): AFC = [ [0, {'CIN', 'BAL', 'CLE', 'PIT'}, 'AFC North'], [0, {'NWE', 'BUF', 'MIA', 'NYJ'}, 'AFC East'], [0, {'KAN', 'LAC', 'DEN', 'LVR'}, 'AFC West'], [0, {'HOU', 'JAX', 'TEN', 'IND'}, 'AFC South'] ] NFC = [ [0, {'GNB', 'MIN', 'DET', 'CHI'}, 'NFC North'], [0, {'PHI', 'DAL', 'WAS', 'NYG'}, 'NFC East'], [0, {'LAR', 'ARI', 'SEA', 'SFO'}, 'NFC West'], [0, {'TAM', 'NOR', 'CAR', 'ATL'}, 'NFC South'] ] return AFC, NFC def wdraft(draft_year, writer): AFC, NFC = reset_divisions() with open(f'csvs/AP{draft_year}.csv', 'r+') as csv_file: csv_reader = csv.DictReader(csv_file) for row in csv_reader: # 修正逻辑优先级,确保先判断是否为All-Pro,再排除特殊位置 if ('AP: 1st Tm' in row['All-pro teams'] or 'AP: 2nd Tm' in row['All-pro teams']) and row['Pos'] not in specialists: for i in range(len(AFC)): if row['Tm'] in AFC[i][1]: AFC[i][0] += 1 elif row['Tm'] in NFC[i][1]: NFC[i][0] += 1 # 简化跨队处理逻辑 if '2TM' in row['Tm']: print(row['Player']) exc = int(input("Where do you want to put him?\n 0-7 (AFC-NFC, N,E,W,S)")) all_divisions = AFC + NFC if 0 <= exc < len(all_divisions): all_divisions[exc][0] += 1 # 合并AFC和NFC的写入逻辑,减少重复代码 for division in AFC + NFC: # 这里可以直接用变量,也可以用f-string,效果完全一致 writer.writerow({ 'Div': division[2], 'Yr': draft_year, 'AP': division[0] }) return f'{draft_year} was successfully loaded' # 主执行逻辑 with open("All-Pros_1970-2022.csv", 'w', newline="") as csvfile: fieldnames = ['Div', 'Yr', 'AP'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() print(wdraft(2022, writer))
内容的提问来源于stack exchange,提问作者mactatum
相关产品推荐
相关产品推荐

