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

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引发错误。

修复建议

  1. 提前初始化文件句柄:在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 
  1. 捕获并记录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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 10:27:44