Python 2.7 copyfile报错:仅目标文件触发UnboundLocalError
问题分析:UnboundLocalError: local variable 'fout' referenced before assignment
问题场景
将文件从源路径复制到目标路径,源文件确认存在,但执行os.close(fout)时触发UnboundLocalError,提示fout未定义就被引用。仅部分文件出现该异常,疑惑os.open(dst, WRITE_FLAGS, stat.st_mode)或os.write(fout, x)未抛出异常。
错误详情
错误栈显示:
UnboundLocalError: local variable 'fout' referenced before assignment
涉及代码
import os import traceback class CTError(Exception): def __init__(self, errors): self.errors = errors try: O_BINARY = os.O_BINARY except: O_BINARY = 0 READ_FLAGS = os.O_RDONLY | O_BINARY WRITE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_TRUNC | O_BINARY BUFFER_SIZE = 128*1024 def copyfile(src, dst): try: fin = os.open(src, READ_FLAGS) stat = os.fstat(fin) fout = os.open(dst, WRITE_FLAGS, stat.st_mode) for x in iter(lambda: os.read(fin, BUFFER_SIZE), ""): os.write(fout, x) finally: try: os.close(fin) except: #fin2 = open("C:\\Users\\testUser\\ScriptErrLogs\\saveErrors.txt", 'a+') #fin2.write(traceback.print_exc()) #fin2.close() pass try: os.close(fout) except: fin2 = open("C:\\Users\\testUser\\ScriptErrLogs\\saveErrors.txt", 'a+') e = str(traceback.print_exc()) fin2.write(e) fin2.close() print os.path.isfile(src) print os.path.isfile(dst) pass DEBUG = 1 f = open('C:\\Users\\testUser\\Scripts\\Python\\testImport.csv','r') lines = f.readlines() for line in lines: temp = line.split('\\') tempFileName = line[0:-1] tempPath = 'C:\\Users\\testUser\\testSaveLocation\\testSave' # DEBUG prints if DEBUG == 0: print '#### LINE ####' print line print '#### FILENAME ####' print tempFileName # Discard the first 3 elements to create the new location path for entry in temp[3:]: tempPath = tempPath + '\\'+ entry # DEBUG prints if DEBUG == 0: print '#### TEMPPATH ####' print tempPath # Check path exists pathExists = os.path.exists(tempPath) # Create directory structure if not pathExists and not '.pdf' in entry: try: os.mkdir(tempPath) except OSError as error: print error # Copy file to new location if '.pdf' in entry: try: copyfile(line[:-1],tempPath[:-1]) except OSError as error: print error
排查方向
fout未初始化的场景:进入finally块前,fout = os.open(...)可能未执行就抛出异常。比如os.fstat(fin)执行失败,或os.open(dst, ...)本身抛错,导致fout未定义就进入finally执行关闭操作。- 异常被静默覆盖:原
try块未显式捕获异常,一旦fin打开后,stat = os.fstat(fin)或fout = os.open(...)抛错,会直接跳转到finally,此时fout未赋值,触发UnboundLocalError,而之前的异常因未被捕获记录,导致误以为前面操作无错误。 - 目标路径问题:调用
copyfile时传入的dst路径可能不存在、权限不足,导致os.open(dst, ...)抛错,直接进入finally引发错误。
修复建议
- 提前初始化文件句柄:在
try块外给fin和fout赋初始值,避免未定义引用:
def copyfile(src, dst): fin = None fout = None try: fin = os.open(src, READ_FLAGS) stat = os.fstat(fin) fout = os.open(dst, WRITE_FLAGS, stat.st_mode) for x in iter(lambda: os.read(fin, BUFFER_SIZE), ""): os.write(fout, x) finally: if fin is not None: try: os.close(fin) except: pass if fout is not None: try: os.close(fout) except: # 异常记录逻辑 fin2 = open("C:\\Users\\testUser\\ScriptErrLogs\\saveErrors.txt", 'a+') e = str(traceback.print_exc()) fin2.write(e) fin2.close() print os.path.isfile(src) print os.path.isfile(dst) pass
- 捕获并记录
try块内的异常:明确排查哪一步操作抛错:
def copyfile(src, dst): fin = None fout = None try: fin = os.open(src, READ_FLAGS) stat = os.fstat(fin) fout = os.open(dst, WRITE_FLAGS, stat.st_mode) for x in iter(lambda: os.read(fin, BUFFER_SIZE), ""): os.write(fout, x) except Exception as e: print(f"Copy error for {src} -> {dst}: {e}") traceback.print_exc() finally: # 关闭逻辑同上
内容的提问来源于stack exchange,提问作者tuck225
相关产品推荐
相关产品推荐

