python3 在文件确实存在的情况下,运行提示找不到文件
提示 [Errno 2] No such file or directory: 但是路径下确实存在此文件,在不改动的情况下,再次运行,执行成功。
百思不得其解,看到此链接下的回答
http://bbs.csdn.net/topics/391934998?page=1
尝试使用 os.path.normpath() 替换os.path.join(),先记录待测试。
-----------------------------------------------------------
使用了以上方法发现并没有解决问题
折腾半天,定位问题在open方法上。
最后得出结论:文件夹名称最后有个空格,会导致失败。问题解决!!
待贴代码。
------------------------------------------------------------------------
错误指向这句
shutil.copy(os.path.normpath('%s\%s' % (otherfilepath, file)), outdirname)
通过单步执行定位问题,出错是在shutil.copy。
下面是shutil.copy源码
1 def copy(src, dst, *, follow_symlinks=True): 2 """Copy data and mode bits ("cp src dst"). Return the file's destination. 3 4 The destination may be a directory. 5 6 If follow_symlinks is false, symlinks won't be followed. This 7 resembles GNU's "cp -P src dst". 8 9 If source and destination are the same file, a SameFileError will be 10 raised. 11 12 """ 13 if os.path.isdir(dst): 14 dst = os.path.join(dst, os.path.basename(src)) 15 copyfile(src, dst, follow_symlinks=follow_symlinks) # 定位到的出错点 16 copymode(src, dst, follow_symlinks=follow_symlinks) 17 return dst
继续查copyfile的源码:
1 def copyfile(src, dst, *, follow_symlinks=True): 2 """Copy data from src to dst. 3 4 If follow_symlinks is not set and src is a symbolic link, a new 5 symlink will be created instead of copying the file it points to. 6 7 """ 8 if _samefile(src, dst): 9 raise SameFileError("{!r} and {!r} are the same file".format(src, dst)) 10 11 for fn in [src, dst]: 12 try: 13 st = os.stat(fn) 14 except OSError: 15 # File most likely does not exist 16 pass 17 else: 18 # XXX What about other special files? (sockets, devices...) 19 if stat.S_ISFIFO(st.st_mode): 20 raise SpecialFileError("`%s` is a named pipe" % fn) 21 22 if not follow_symlinks and os.path.islink(src): 23 os.symlink(os.readlink(src), dst) 24 else: 25 with open(src, 'rb') as fsrc: 26 with open(dst, 'wb') as fdst: # 最终定位错误在这一句 27 copyfileobj(fsrc, fdst) 28 return dst
最后失败原因是open函数出错,无法打开dst文件。
根据源码,执行shutil.copy(srcfile, dstdir),
先是在dstdir文件夹创建一个与srcfile同名的文件路径os.path.join(dst, os.path.basename(src)),即为dstfile的路径。
之后执行copyfile,同时打开srcfile和dstfile,把srcfile的内容复制到dstfile中。
无意中发现dst的文件夹名最后有个空格,因为dst是由前面的代码生成的,在生成的时候,文件夹名字字符串最后有个空格‘test ’,实际生成文件夹的时候会自动把最后的空格去掉,即实际文件夹名为test。
而在程序中dstdir的空格还是保留的,即在执行open的时候打开的文件名是 (‘test \\dstfile’),是寻不到文件的(实际存在的是test\\dstfile),因此把空格去掉就不报错了。