Python脚本字符随机插入遇NameError(rev未定义)求助
问题:Python脚本触发NameError,变量rev未定义
问题描述
我正在编写Python脚本,需求为读取文件每行内容,遍历行内每个字符,从指定字符列表中随机选取字符插入(其中'repl'需替换为空字符串),最终将处理后的内容写入新文件。
现有代码运行时触发NameError,提示变量rev未定义。我原以为循环内定义的变量可全局访问,疑惑该认知是否错误,且暂不想使用函数实现,希望得到相关解决建议。
现有代码
import re import random as rand lettersDict = {} with open('alphabet.txt', 'r') as alpha: try: for i in range(41): letter = alpha.readline() if len(letter) == 2: re.sub('\'\'', '', letter) else: pass print(letter, i) lettersDict[i] = letter print(lettersDict) for k in lettersDict: v = lettersDict[k] rv = re.sub('\n', '', v) print(rv) lettersDict[k] = rv print(lettersDict[k]) finally: alpha.close() lineCount = 0 __NextLine__Count = 0 with open('unalteredOpus_Arcanus.txt', 'r') as uoa: try: for line in uoa: lineCount += 1 print(lineCount) print(line) lineSplit = re.split(' - ', line) print(lineSplit) if len(lineSplit) == 2: rev = lineSplit.pop(1) rev = re.sub(' ', '\'', rev) print(lineSplit, rev) for c in rev: randomizer = rand.randrange(41) print(randomizer) charInsert = lettersDict[randomizer] if charInsert == '\'repl\'': lettersDict[randomizer] = '' charInsert = lettersDict[randomizer] else: pass print(charInsert) strSplit = re.split(c, rev) print(strSplit) print(len(strSplit)) if len(strSplit) >= 2: p1 = strSplit.pop(0) p2 = strSplit.pop(0) rev = "{}{}{}".format(p1, c, p2) else: p1 = strSplit.pop(0) rev = "{}{}".format(p1, c) print(lineSplit, rev) elif len(lineSplit) == 1: __NextLine__Count += 1 lineSplit.pop(0) lineSplit.append('Page {}'.format(__NextLine__Count)) print(lineSplit) else: pass try: with open("alteredOpus_Arcanus.txt", "w") as aoa: aoa.write("{}{}\n".format(lineSplit, rev)) finally: aoa.close() finally: uoa.close()
解决建议
1. 变量作用域问题的根源
你的认知有误:Python中循环内定义的变量确实能在循环外部访问,但只有当代码执行到定义变量的分支时,变量才会被创建。你的代码里,rev只在len(lineSplit) == 2的分支里定义,如果某一行触发len(lineSplit) == 1或else分支,rev根本没被初始化,后续写入文件时自然会抛出NameError。
2. 直接解决办法
在处理每一行的开头,提前初始化rev为默认值,确保无论走哪个分支,变量都存在:
for line in uoa: lineCount += 1 print(lineCount) print(line) rev = "" # 提前初始化rev lineSplit = re.split(' - ', line) # 后续代码不变...
然后在len(lineSplit) == 1的分支里,根据需求设置rev的内容,比如保持为空:
elif len(lineSplit) == 1: __NextLine__Count += 1 lineSplit.pop(0) lineSplit.append('Page {}'.format(__NextLine__Count)) rev = "" # 按需设置rev内容 print(lineSplit)
3. 额外代码优化(可选)
with语句会自动处理文件关闭,代码里所有的.close()调用都是多余的,直接删掉即可;- 写入文件时用
"w"模式会每次清空文件,改成"a"(追加模式)才能保留所有行的处理结果; re.sub('\'\'', '', letter)不会修改原字符串,需要把结果赋值给letter:letter = re.sub('\'\'', '', letter),否则这行代码无效;- 判断
charInsert == '\'repl\''可能不符合实际数据,建议改成charInsert == 'repl'(如果alphabet.txt里的repl是无引号的)。
内容的提问来源于stack exchange,提问作者Dimir
相关产品推荐
相关产品推荐

